int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif int T; scanf("%d", &T); for(int ck=1; ck<=T; ck++) { CLR(to); int N; scanf("%d", &N); for(int i=1,f,t; i<=N; i++) { scanf("%d%d", &f, &t); to[f]=t; } am.construct(to); am.gauss(); printf("Case %d: %.7f\n", ck, am.x[0]); } return 0; }
KOKKOS_INLINE_FUNCTION void operator() (const team_member& dev) const { Kokkos::parallel_for(Kokkos::TeamThreadRange(dev,0,rows_per_team), [&] (const ordinal_type& loop) { const ordinal_type iRow = static_cast<ordinal_type> ( dev.league_rank() ) * rows_per_team + loop; if (iRow >= m_A.numRows ()) { return; } const KokkosSparse::SparseRowViewConst<AMatrix> row = m_A.rowConst(iRow); const ordinal_type row_length = static_cast<ordinal_type> (row.length); value_type sum = 0; Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(dev,row_length), [&] (const ordinal_type& iEntry, value_type& lsum) { const value_type val = conjugate ? ATV::conj (row.value(iEntry)) : row.value(iEntry); lsum += val * m_x(row.colidx(iEntry)); },sum); Kokkos::single(Kokkos::PerThread(dev), [&] () { sum *= alpha; if (dobeta == 0) { m_y(iRow) = sum ; } else { m_y(iRow) = beta * m_y(iRow) + sum; } }); }); }
/// Implements the "zoomout" operation. Enlarges the view of the scene. void zoomOut() { AMatrix<float> mT; mT.identity(); mT.scaling(1.0 / 1.2); sceneT = mT*sceneT; }
void test_randomDiscrete(int n, int m, int repeats=1) { ASSERT_TRUE(N==n||N==Dynamic); ASSERT_TRUE(M==m||M==Dynamic); typedef typename Eigen::Matrix<Scalar,N,N> AMatrix; typedef typename Eigen::Matrix<Scalar,N,1> AVector; typedef typename Eigen::Matrix<Scalar,N,M> BMatrix; typedef typename Eigen::Matrix<Scalar,M,N> GMatrix; typedef typename Eigen::Matrix<Scalar,M,M> WMatrix; AMatrix Q = AMatrix::Random(n,n); Q*=Q.transpose(); WMatrix R = WMatrix::Random(m,m); R*=R.transpose(); GMatrix G(m,n); for(int i=0;i<repeats;++i) { const AMatrix & A = 3*AMatrix::Random(n,n); const BMatrix & B = 3*BMatrix::Random(n,m); if(LQR::isCommandable(A,B)) { LQR::LQRDP<AMatrix,BMatrix,AMatrix,BMatrix>::run(A,B,Q,Q,R,0.01,G); const AVector & x0 = AVector::Random(n,1); ASSERT_TRUE(test_convergenceDiscrete(A+B*G,x0)); ASSERT_TRUE(LQR::isConvergingDiscrete(A,B,G)); } } }
void test_random(int n, int m, int repeats=1) { ASSERT_TRUE(N==n||N==Dynamic); ASSERT_TRUE(M==m||M==Dynamic); typedef typename Eigen::Matrix<Scalar,N,N> AMatrix; typedef typename Eigen::Matrix<Scalar,N,1> AVector; typedef typename Eigen::Matrix<Scalar,N,M> BMatrix; typedef typename Eigen::Matrix<Scalar,M,N> GMatrix; typedef typename Eigen::Matrix<Scalar,M,M> WMatrix; GMatrix G(m,n); for(int i=0;i<repeats;++i) { AMatrix Q = AMatrix::Random(n,n); Q*=Q.transpose(); WMatrix R = WMatrix::Random(m,m); R*=R.transpose(); const AMatrix & A = AMatrix::Random(n,n); const BMatrix & B = BMatrix::Random(n,m); if(LQR::isCommandable(A,B)) { LQR::LQRDP<AMatrix,BMatrix,AMatrix,BMatrix>::runContinuous(A,B,Q,R,G); ASSERT_TRUE(LQR::isConverging(A,B,G)); //This test might fail for big matrices => disabled // const AVector & x0 = 10*AVector::Random(n,1); // ASSERT_TRUE(test_convergence(A+B*G,x0,0.1)); } } }
/** * @brief Checks affine matrix to ensure it is a 3x3 standard form transform * * @param am Affine matrix to validate */ void Affine::checkDims(const AMatrix &am) const throw (iException &) { if ((am.dim1() != 3) && (am.dim2() != 3)) { ostringstream mess; mess << "Affine matrices must be 3x3 - this one is " << am.dim1() << "x" << am.dim2(); throw iException::Message(iException::Programmer, mess.str(), _FILEINFO_); } return; }
Vector<T> operator*(const AMatrix<T>& lhs, const Vector<T>& rhs) { assert(lhs.cols() == rhs.size()); Vector<T> ret(lhs.rows()); for(int i=0; i<lhs.rows(); ++i) { ret[i] = lhs.getRow(i)*rhs; } return ret; }
void main333(){ double A[3]={-0.5900,-0.2781,0.4227}; double B[3]={-1.6702, 0.4716,-1.2128}; double C[3]={0.6538,0.4942,0.7791}; double D[3]={0.7150,0.9037,0.8909}; double M[3]; AMatrix a; a.Mean(A,B,C,D,M,4); a.CoVariance(A,B,C,D,M); cin.get(); }
/// OpenGL initializations void init() { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); // lighting setup GLfloat mat_A[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat mat_D[] = { 0.5, 0.0, 0.75, 1.0 }; GLfloat mat_S[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat shine[] = { 128.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_A); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_D); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_S); glMaterialfv(GL_FRONT, GL_SHININESS, shine); GLfloat left_light_position[] = { 0.0f, 2.0f, 2.0f, 0.0f }; GLfloat right_light_position[] = { 0.0f, -2.0f, 2.0f, 0.0f }; GLfloat left_diffuse_light[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat right_diffuse_light[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, left_light_position); glLightfv(GL_LIGHT1, GL_POSITION, right_light_position); glLightfv(GL_LIGHT0, GL_DIFFUSE, left_diffuse_light); glLightfv(GL_LIGHT1, GL_DIFFUSE, right_diffuse_light); glClearColor(1, 1, 1, 1); glColor4f(1, 1, 0, 1); rendermode = SMOOTH; sceneT.identity(); std::time(&start); frame = 0; }
/** * @brief Compute the inverse of a matrix * * This method will compute the inverse of an affine matrix for purposes of * forward and inverse Affine computations. * * @param a Matrix to invert * * @return Affine::AMatrix The inverted matrix */ Affine::AMatrix Affine::invert(const AMatrix &a) const throw (iException &) { // Now compute the inverse affine matrix using singular value // decomposition A = USV'. So invA = V invS U'. Where ' represents // the transpose of a matrix and invS is S with the recipricol of the // diagonal elements JAMA::SVD<double> svd(a); AMatrix V; svd.getV(V); // The inverse of S is 1 over each diagonal element of S AMatrix invS; svd.getS(invS); for (int i=0; i<invS.dim1(); i++) { if (invS[i][i] == 0.0) { string msg = "Affine transform not invertible"; throw iException::Message(iException::Math,msg,_FILEINFO_); } invS[i][i] = 1.0 / invS[i][i]; } // Transpose U AMatrix U; svd.getU(U); AMatrix transU(U.dim2(),U.dim1()); for (int r=0; r<U.dim1(); r++) { for (int c=0; c<U.dim2(); c++) { transU[c][r] = U[r][c]; } } // Multiply stuff together to get the inverse of the affine AMatrix VinvS = TNT::matmult(V,invS); return (TNT::matmult(VinvS,transU)); }
bool AMatrix<T>::isEqual(const AMatrix<T>& other) const { if(this->rows() != other.rows() || this->cols() != other.cols()) { return false; } for(SizeType i = 0; i < this->rows(); i++) { for(SizeType j = 0; j < this->cols(); j++) { if(this->get(i, j) != other.get(i, j)) { return false; } } } return true; }
/// Mouse move function void mousemove(int x, int y) { if (buttonpressed == GLUT_MIDDLE_BUTTON) { // rotations handler AMatrix<float> mT; arcball.drag(x, winh - y, &mT); sceneT = mT*sceneIniT; } else if (buttonpressed == GLUT_RIGHT_BUTTON) { // translations handler double xw, yw, zw; screenToWorld(x, winh - y, xw, yw, zw); AMatrix<float> mT; mT.identity(); mT.translation(xw - xwini, yw - ywini, zw - zwini); sceneT = mT*sceneIniT; } else if (buttonpressed == GLUT_LEFT_BUTTON) { Point2 p(x, winh - y); stroke.push_back(p); } glutPostRedisplay(); }
static std::shared_ptr< backend::crs<Val, Col, Ptr> > interpolation( const AMatrix &A, const std::vector<Val> &Adia, const backend::crs<Val, Col, Ptr> &P_tent, std::vector<Val> &omega ) { const size_t n = rows(P_tent); const size_t nc = cols(P_tent); auto AP = product(A, P_tent, /*sort rows: */true); omega.resize(nc, math::zero<Val>()); std::vector<Val> denum(nc, math::zero<Val>()); #pragma omp parallel { std::vector<ptrdiff_t> marker(nc, -1); // Compute A * Dinv * AP row by row and compute columnwise // scalar products necessary for computation of omega. The // actual results of matrix-matrix product are not stored. std::vector<Col> adap_col(128); std::vector<Val> adap_val(128); #pragma omp for for(ptrdiff_t ia = 0; ia < static_cast<ptrdiff_t>(n); ++ia) { adap_col.clear(); adap_val.clear(); // Form current row of ADAP matrix. for(auto a = A.row_begin(ia); a; ++a) { Col ca = a.col(); Val va = math::inverse(Adia[ca]) * a.value(); for(auto p = AP->row_begin(ca); p; ++p) { Col c = p.col(); Val v = va * p.value(); if (marker[c] < 0) { marker[c] = adap_col.size(); adap_col.push_back(c); adap_val.push_back(v); } else { adap_val[marker[c]] += v; } } } amgcl::detail::sort_row( &adap_col[0], &adap_val[0], adap_col.size() ); // Update columnwise scalar products (AP,ADAP) and (ADAP,ADAP). // 1. (AP, ADAP) for( Ptr ja = AP->ptr[ia], ea = AP->ptr[ia + 1], jb = 0, eb = adap_col.size(); ja < ea && jb < eb; ) { Col ca = AP->col[ja]; Col cb = adap_col[jb]; if (ca < cb) ++ja; else if (cb < ca) ++jb; else /*ca == cb*/ { Val v = AP->val[ja] * adap_val[jb]; #pragma omp critical omega[ca] += v; ++ja; ++jb; } } // 2. (ADAP, ADAP) (and clear marker) for(size_t j = 0, e = adap_col.size(); j < e; ++j) { Col c = adap_col[j]; Val v = adap_val[j]; #pragma omp critical denum[c] += v * v; marker[c] = -1; } } } for(size_t i = 0, m = omega.size(); i < m; ++i) omega[i] = math::inverse(denum[i]) * omega[i]; // Update AP to obtain P: P = (P_tent - D^-1 A P Omega) /* * Here we use the fact that if P(i,j) != 0, * then with necessity AP(i,j) != 0: * * AP(i,j) = sum_k(A_ik P_kj), and A_ii != 0. */ #pragma omp parallel for for(ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(n); ++i) { Val dia = math::inverse(Adia[i]); for(Ptr ja = AP->ptr[i], ea = AP->ptr[i+1], jp = P_tent.ptr[i], ep = P_tent.ptr[i+1]; ja < ea; ++ja ) { Col ca = AP->col[ja]; Val va = -dia * AP->val[ja] * omega[ca]; for(; jp < ep; ++jp) { Col cp = P_tent.col[jp]; if (cp > ca) break; if (cp == ca) { va += P_tent.val[jp]; break; } } AP->val[ja] = va; } } return AP; }
void spmv(const char mode[], const AlphaType& alpha, const AMatrix& A, const XVector& x, const BetaType& beta, const YVector& y, const RANK_ONE) { #ifdef KOKKOS_HAVE_CXX11 // Make sure that both x and y have the same rank. static_assert ((int) XVector::rank == (int) YVector::rank, "KokkosBlas::spmv: Vector ranks do not match."); // Make sure that x (and therefore y) is rank 1. static_assert ((int) XVector::rank == 1, "KokkosBlas::spmv: " "Both Vector inputs must have rank 1 or 2."); // Make sure that y is non-const. static_assert (Kokkos::Impl::is_same<typename YVector::value_type, typename YVector::non_const_value_type>::value, "KokkosBlas::spmv: Output Vector must be non-const."); #else // We prefer to use C++11 static_assert, because it doesn't give // "unused typedef" warnings, like the constructs below do. // // Make sure that both x and y have the same rank. typedef typename Kokkos::Impl::StaticAssert<(int) XVector::rank == (int) YVector::rank>::type Blas1_spmv_vector_ranks_do_not_match; // Make sure that x (and therefore y) is rank 1. typedef typename Kokkos::Impl::StaticAssert<(int) XVector::rank == 1 >::type Blas1_spmv_vector_rank_not_one; #endif // KOKKOS_HAVE_CXX11 // Check compatibility of dimensions at run time. if((mode[0]==NoTranspose[0])||(mode[0]==Conjugate[0])) { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (x.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (y.dimension_0 ()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match: " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1() << ", y: " << y.dimension_0 () << " x " << y.dimension_1() ; Kokkos::Impl::throw_runtime_exception (os.str ()); } } else { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (y.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (x.dimension_0()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match (transpose): " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1() << ", y: " << y.dimension_0 () << " x " << y.dimension_1() ; Kokkos::Impl::throw_runtime_exception (os.str ()); } } typedef KokkosSparse::CrsMatrix<typename AMatrix::const_value_type, typename AMatrix::non_const_ordinal_type, typename AMatrix::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged>, typename AMatrix::const_size_type> AMatrix_Internal; typedef Kokkos::View<typename XVector::const_value_type*, typename XVector::array_layout, typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > XVector_Internal; typedef Kokkos::View<typename YVector::non_const_value_type*, typename YVector::array_layout, typename YVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > YVector_Internal; AMatrix_Internal A_i = A; XVector_Internal x_i = x; YVector_Internal y_i = y; return Impl::SPMV<typename AMatrix_Internal::value_type, typename AMatrix_Internal::ordinal_type, typename AMatrix_Internal::device_type, typename AMatrix_Internal::memory_traits, typename AMatrix_Internal::size_type, typename XVector_Internal::value_type*, typename XVector_Internal::array_layout, typename XVector_Internal::device_type, typename XVector_Internal::memory_traits, typename YVector_Internal::value_type*, typename YVector_Internal::array_layout, typename YVector_Internal::device_type, typename YVector_Internal::memory_traits>::spmv(mode,alpha,A,x,beta,y); }
void spmv(const char mode[], const AlphaType& alpha_in, const AMatrix& A, const XVector& x, const BetaType& beta_in, const YVector& y, const RANK_TWO) { typedef typename Impl::GetCoeffView<AlphaType, typename XVector::device_type>::view_type alpha_view_type; typedef typename Impl::GetCoeffView<BetaType, typename XVector::device_type>::view_type beta_view_type; //alpha_view_type alpha = Impl::GetCoeffView<AlphaType, typename XVector::device_type>::get_view(alpha_in,x.dimension_1()); //beta_view_type beta = Impl::GetCoeffView<AlphaType, typename XVector::device_type>::get_view(beta_in, x.dimension_1()); #ifdef KOKKOS_HAVE_CXX11 // Make sure that both x and y have the same rank. static_assert (XVector::rank == YVector::rank, "KokkosBlas::spmv: Vector ranks do not match."); // Make sure that y is non-const. static_assert (Kokkos::Impl::is_same<typename YVector::value_type, typename YVector::non_const_value_type>::value, "KokkosBlas::spmv: Output Vector must be non-const."); #else // We prefer to use C++11 static_assert, because it doesn't give // "unused typedef" warnings, like the constructs below do. // // Make sure that both x and y have the same rank. typedef typename Kokkos::Impl::StaticAssert<XVector::rank == YVector::rank>::type Blas1_spmv_vector_ranks_do_not_match; #endif // KOKKOS_HAVE_CXX11 // Check compatibility of dimensions at run time. if((mode[0]==NoTranspose[0])||(mode[0]==Conjugate[0])) { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (x.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (y.dimension_0 ()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match: " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1 () << ", y: " << y.dimension_0 () << " x " << y.dimension_1 (); Kokkos::Impl::throw_runtime_exception (os.str ()); } } else { if ((x.dimension_1 () != y.dimension_1 ()) || (static_cast<size_t> (A.numCols ()) > static_cast<size_t> (y.dimension_0 ())) || (static_cast<size_t> (A.numRows ()) > static_cast<size_t> (x.dimension_0 ()))) { std::ostringstream os; os << "KokkosBlas::spmv: Dimensions do not match (transpose): " << ", A: " << A.numRows () << " x " << A.numCols() << ", x: " << x.dimension_0 () << " x " << x.dimension_1 () << ", y: " << y.dimension_0 () << " x " << y.dimension_1 (); Kokkos::Impl::throw_runtime_exception (os.str ()); } } typedef KokkosSparse::CrsMatrix<typename AMatrix::const_value_type, typename AMatrix::const_ordinal_type, typename AMatrix::device_type, typename AMatrix::memory_traits, typename AMatrix::const_size_type> AMatrix_Internal; AMatrix_Internal A_i = A; // Call single vector version if appropriate if( x.dimension_1() == 1) { typedef Kokkos::View<typename XVector::const_value_type*, typename Kokkos::Impl::if_c<Kokkos::Impl::is_same<typename YVector::array_layout,Kokkos::LayoutLeft>::value, Kokkos::LayoutLeft,Kokkos::LayoutStride>::type, typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > XVector_SubInternal; typedef Kokkos::View<typename YVector::non_const_value_type*, typename Kokkos::Impl::if_c<Kokkos::Impl::is_same<typename YVector::array_layout,Kokkos::LayoutLeft>::value, Kokkos::LayoutLeft,Kokkos::LayoutStride>::type, typename YVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > YVector_SubInternal; XVector_SubInternal x_i = Kokkos::subview(x,Kokkos::ALL(),0); YVector_SubInternal y_i = Kokkos::subview(y,Kokkos::ALL(),0); alpha_view_type alpha = Impl::GetCoeffView<AlphaType, typename XVector::device_type>::get_view(alpha_in,x.dimension_1()); beta_view_type beta = Impl::GetCoeffView<BetaType, typename XVector::device_type>::get_view(beta_in, x.dimension_1()); typename alpha_view_type::non_const_type::HostMirror h_alpha = Kokkos::create_mirror_view(alpha); Kokkos::deep_copy(h_alpha,alpha); typename beta_view_type::non_const_type::HostMirror h_beta = Kokkos::create_mirror_view(beta); Kokkos::deep_copy(h_beta,beta); spmv(mode,h_alpha(0),A,x_i,h_beta(0),y_i); return; } else { typedef Kokkos::View<typename XVector::const_value_type**, typename XVector::array_layout, typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > XVector_Internal; typedef Kokkos::View<typename YVector::non_const_value_type**, typename YVector::array_layout, typename YVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > YVector_Internal; XVector_Internal x_i = x; YVector_Internal y_i = y; typedef Kokkos::View<typename alpha_view_type::const_value_type*, typename alpha_view_type::array_layout, typename alpha_view_type::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > alpha_view_type_Internal; typedef Kokkos::View<typename beta_view_type::const_value_type*, typename beta_view_type::array_layout, typename beta_view_type::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> > beta_view_type_Internal; //alpha_view_type_Internal alpha_c = alpha; //beta_view_type_Internal beta_c = beta; return Impl::SPMV_MV<typename alpha_view_type_Internal::value_type*, typename alpha_view_type_Internal::array_layout, typename alpha_view_type_Internal::device_type, typename alpha_view_type_Internal::memory_traits, typename AMatrix_Internal::value_type, typename AMatrix_Internal::ordinal_type, typename AMatrix_Internal::device_type, typename AMatrix_Internal::memory_traits, typename AMatrix_Internal::size_type, typename XVector_Internal::value_type**, typename XVector_Internal::array_layout, typename XVector_Internal::device_type, typename XVector_Internal::memory_traits, typename beta_view_type_Internal::value_type*, typename beta_view_type_Internal::array_layout, typename beta_view_type_Internal::device_type, typename beta_view_type_Internal::memory_traits, typename YVector_Internal::value_type**, typename YVector_Internal::array_layout, typename YVector_Internal::device_type, typename YVector_Internal::memory_traits>::spmv_mv(mode,alpha_in,A,x,beta_in,y); } }
SEXP cpp_sampleGlm(SEXP r_interface) { // ---------------------------------------------------------------------------------- // extract arguments // ---------------------------------------------------------------------------------- r_interface = CDR(r_interface); List rcpp_model(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_data(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_fpInfos(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_ucInfos(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_fixInfos(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_distribution(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_searchConfig(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_options(CAR(r_interface)); r_interface = CDR(r_interface); List rcpp_marginalz(CAR(r_interface)); // ---------------------------------------------------------------------------------- // unpack the R objects // ---------------------------------------------------------------------------------- // data: const NumericMatrix n_x = rcpp_data["x"]; const AMatrix x(n_x.begin(), n_x.nrow(), n_x.ncol()); const NumericMatrix n_xCentered = rcpp_data["xCentered"]; const AMatrix xCentered(n_xCentered.begin(), n_xCentered.nrow(), n_xCentered.ncol()); const NumericVector n_y = rcpp_data["y"]; const AVector y(n_y.begin(), n_y.size()); const IntVector censInd = as<IntVector>(rcpp_data["censInd"]); // FP configuration: // vector of maximum fp degrees const PosIntVector fpmaxs = as<PosIntVector>(rcpp_fpInfos["fpmaxs"]); // corresponding vector of fp column indices const PosIntVector fppos = rcpp_fpInfos["fppos"]; // corresponding vector of power set cardinalities const PosIntVector fpcards = rcpp_fpInfos["fpcards"]; // names of fp terms const StrVector fpnames = rcpp_fpInfos["fpnames"]; // UC configuration: const PosIntVector ucIndices = rcpp_ucInfos["ucIndices"]; List rcpp_ucColList = rcpp_ucInfos["ucColList"]; std::vector<PosIntVector> ucColList; for (R_len_t i = 0; i != rcpp_ucColList.length(); ++i) { ucColList.push_back(as<PosIntVector>(rcpp_ucColList[i])); } // fixed covariate configuration: const PosIntVector fixIndices = rcpp_fixInfos["fixIndices"]; List rcpp_fixColList = rcpp_fixInfos["fixColList"]; std::vector<PosIntVector> fixColList; for (R_len_t i = 0; i != rcpp_fixColList.length(); ++i) { fixColList.push_back(as<PosIntVector>(rcpp_fixColList[i])); } // distributions info: const double nullModelLogMargLik = as<double>(rcpp_distribution["nullModelLogMargLik"]); const double nullModelDeviance = as<double>(rcpp_distribution["nullModelDeviance"]); S4 rcpp_gPrior = rcpp_distribution["gPrior"]; List rcpp_family = rcpp_distribution["family"]; const bool tbf = as<bool>(rcpp_distribution["tbf"]); const bool doGlm = as<bool>(rcpp_distribution["doGlm"]); const double empiricalMean = as<double>(rcpp_distribution["yMean"]); const bool empiricalgPrior = as<bool>(rcpp_distribution["empiricalgPrior"]); // model search configuration: const bool useFixedc = as<bool>(rcpp_searchConfig["useFixedc"]); // options: const bool estimateMargLik = as<bool>(rcpp_options["estimateMargLik"]); const bool verbose = as<bool>(rcpp_options["verbose"]); const bool debug = as<bool>(rcpp_options["debug"]); const bool isNullModel = as<bool>(rcpp_options["isNullModel"]); const bool useFixedZ = as<bool>(rcpp_options["useFixedZ"]); const double fixedZ = as<double>(rcpp_options["fixedZ"]); #ifdef _OPENMP const bool useOpenMP = as<bool>(rcpp_options["useOpenMP"]); #endif S4 rcpp_mcmc = rcpp_options["mcmc"]; const PosInt iterations = rcpp_mcmc.slot("iterations"); const PosInt burnin = rcpp_mcmc.slot("burnin"); const PosInt step = rcpp_mcmc.slot("step"); // z density stuff: const RFunction logMarginalZdens(as<SEXP>(rcpp_marginalz["logDens"])); const RFunction marginalZgen(as<SEXP>(rcpp_marginalz["gen"])); // ---------------------------------------------------------------------------------- // further process arguments // ---------------------------------------------------------------------------------- // data: // only the intercept is always included, that is fixed, in the model IntSet fixedCols; fixedCols.insert(1); // totalnumber is set to 0 because we do not care about it. const DataValues data(x, xCentered, y, censInd, 0, fixedCols); // FP configuration: const FpInfo fpInfo(fpcards, fppos, fpmaxs, fpnames, x); // UC configuration: // determine sizes of the UC groups, and the total size == maximum size reached together by all // UC groups. PosIntVector ucSizes; PosInt maxUcDim = 0; for (std::vector<PosIntVector>::const_iterator cols = ucColList.begin(); cols != ucColList.end(); ++cols) { PosInt thisSize = cols->size(); maxUcDim += thisSize; ucSizes.push_back(thisSize); } const UcInfo ucInfo(ucSizes, maxUcDim, ucIndices, ucColList); // fix configuration: // determine sizes of the fix groups, and the total size == maximum size reached together by all // UC groups. PosIntVector fixSizes; PosInt maxFixDim = 0; for (std::vector<PosIntVector>::const_iterator cols = fixColList.begin(); cols != fixColList.end(); ++cols) { PosInt thisSize = cols->size(); maxFixDim += thisSize; fixSizes.push_back(thisSize); } const FixInfo fixInfo(fixSizes, maxFixDim, fixIndices, fixColList); // model configuration: GlmModelConfig config(rcpp_family, nullModelLogMargLik, nullModelDeviance, exp(fixedZ), rcpp_gPrior, data.response, debug, useFixedc, empiricalMean, empiricalgPrior); // model config/info: const Model thisModel(ModelPar(rcpp_model["configuration"], fpInfo), GlmModelInfo(as<List>(rcpp_model["information"]))); // the options const Options options(estimateMargLik, verbose, debug, isNullModel, useFixedZ, tbf, doGlm, iterations, burnin, step); // marginal z stuff const MarginalZ marginalZ(logMarginalZdens, marginalZgen); // use only one thread if we do not want to use openMP. #ifdef _OPENMP if(! useOpenMP) { omp_set_num_threads(1); } else { omp_set_num_threads(omp_get_num_procs()); } #endif // ---------------------------------------------------------------------------------- // prepare the sampling // ---------------------------------------------------------------------------------- Fitter fitter; int nCoefs; if(options.doGlm) { // construct IWLS object, which can be used for all IWLS stuff, // and also contains the design matrix etc fitter.iwlsObject = new Iwls(thisModel.par, data, fpInfo, ucInfo, fixInfo, config, config.linPredStart, options.useFixedZ, EPS, options.debug, options.tbf); nCoefs = fitter.iwlsObject->nCoefs; // check that we have the same answer about the null model as R //assert(fitter.iwlsObject->isNullModel == options.isNullModel); if(fitter.iwlsObject->isNullModel != options.isNullModel){ Rcpp::stop("sampleGlm.cpp:cpp_sampleGlm: isNullModel != options.isNullModel"); } } else { AMatrix design = getDesignMatrix(thisModel.par, data, fpInfo, ucInfo, fixInfo, false); fitter.coxfitObject = new Coxfit(data.response, data.censInd, design, config.weights, config.offsets, 1); // the number of coefficients (here it does not include the intercept!!) nCoefs = design.n_cols; // check that we do not have a null model here: // assert(nCoefs > 0); if(nCoefs <= 0){ Rcpp::stop("sampleGlm.cpp:cpp_sampleGlm: nCoefs <= 0"); } } // allocate sample container Samples samples(nCoefs, options.nSamples); // count how many proposals we have accepted: PosInt nAccepted(0); // at what z do we start? double startZ = useFixedZ ? fixedZ : thisModel.info.zMode; // start container with current things Mcmc now(marginalZ, data.nObs, nCoefs); if(doGlm) { // get the mode for beta given the mode of the approximated marginal posterior as z // if TBF approach is used, this will be the only time the IWLS is used, // because we only need the MLE and the Cholesky factor of its // precision matrix estimate, which do not depend on z. PosInt iwlsIterations = fitter.iwlsObject->startWithNewLinPred(40, // this is the corresponding g exp(startZ), // and the start value for the linear predictor is taken from the Glm model config config.linPredStart); // echo debug-level message? if(options.debug) { Rprintf("\ncpp_sampleGlm: Initial IWLS for high density point finished after %d iterations", iwlsIterations); } // this is the current proposal info: now.proposalInfo = fitter.iwlsObject->getResults(); // and this is the current parameters sample: now.sample = Parameter(now.proposalInfo.coefs, startZ); if(options.tbf) { // we will not compute this in the TBF case: now.logUnPosterior = R_NaReal; // start to compute the variance of the intercept parameter: // here the inverse cholesky factor of the precision matrix will // be stored. First, it's the identity matrix. AMatrix inverseQfactor = arma::eye(now.proposalInfo.qFactor.n_rows, now.proposalInfo.qFactor.n_cols); // do the inversion trs(false, false, now.proposalInfo.qFactor, inverseQfactor); // now we can compute the variance of the intercept estimate: const AVector firstCol = inverseQfactor.col(0); const double interceptVar = arma::dot(firstCol, firstCol); // ok, now alter the qFactor appropriately to reflect the // independence assumption between the intercept estimate // and the other coefficients estimates now.proposalInfo.qFactor.col(0) = arma::zeros<AVector>(now.proposalInfo.qFactor.n_rows); now.proposalInfo.qFactor(0, 0) = sqrt(1.0 / interceptVar); } else { // compute the (unnormalized) log posterior of the proposal now.logUnPosterior = fitter.iwlsObject->computeLogUnPosteriorDens(now.sample); } } else { PosInt coxfitIterations = fitter.coxfitObject->fit(); CoxfitResults coxResults = fitter.coxfitObject->finalizeAndGetResults(); fitter.coxfitObject->checkResults(); // echo debug-level message? if(options.debug) { Rprintf("\ncpp_sampleGlm: Cox fit finished after %d iterations", coxfitIterations); } // we will not compute this in the TBF case: now.logUnPosterior = R_NaReal; // compute the Cholesky factorization of the covariance matrix int info = potrf(false, coxResults.imat); // check that all went well if(info != 0) { std::ostringstream stream; stream << "dpotrf(coxResults.imat) got error code " << info << "in sampleGlm"; throw std::domain_error(stream.str().c_str()); } // compute the precision matrix, using the Cholesky factorization // of the covariance matrix now.proposalInfo.qFactor = arma::eye(now.proposalInfo.qFactor.n_rows, now.proposalInfo.qFactor.n_cols); info = potrs(false, coxResults.imat, now.proposalInfo.qFactor); // check that all went well if(info != 0) { std::ostringstream stream; stream << "dpotrs(coxResults.imat, now.proposalInfo.qFactor) got error code " << info << "in sampleGlm"; throw std::domain_error(stream.str().c_str()); } // compute the Cholesky factorization of the precision matrix info = potrf(false, now.proposalInfo.qFactor); // check that all went well if(info != 0) { std::ostringstream stream; stream << "dpotrf(now.proposalInfo.qFactor) got error code " << info << "in sampleGlm"; throw std::domain_error(stream.str().c_str()); } // the MLE of the coefficients now.proposalInfo.coefs = coxResults.coefs; } // so the parameter object "now" is then also the high density point // required for the marginal likelihood estimate: const Mcmc highDensityPoint(now); // we accept this starting value, so initialize "old" with the same ones Mcmc old(now); // ---------------------------------------------------------------------------------- // start sampling // ---------------------------------------------------------------------------------- // echo debug-level message? if(options.debug) { if(tbf) { Rprintf("\ncpp_sampleGlm: Starting MC simulation"); } else { Rprintf("\ncpp_sampleGlm: Starting MCMC loop"); } } // i_iter starts at 1 !! for(PosInt i_iter = 1; i_iter <= options.iterations; ++i_iter) { // echo debug-level message? if(options.debug) { Rprintf("\ncpp_sampleGlm: Starting iteration no. %d", i_iter); } // ---------------------------------------------------------------------------------- // store the proposal // ---------------------------------------------------------------------------------- // sample one new log covariance factor z (other arguments than 1 are not useful // with the current setup of the RFunction wrapper class) now.sample.z = marginalZ.gen(1); if(options.tbf) { if(options.isNullModel) { // note that we do not encounter this in the Cox case // assert(options.doGlm); if(!options.doGlm){ Rcpp::stop("sampleGlm.cpp:cpp_sampleGlm: options.doGlm should be TRUE"); } // draw the proposal coefs, which is here just the intercept now.sample.coefs = drawNormalVector(now.proposalInfo.coefs, now.proposalInfo.qFactor); } else { // here we have at least one non-intercept coefficient // get vector from N(0, I) AVector w = drawNormalVariates(now.proposalInfo.coefs.n_elem, 0.0, 1.0); // then solve L' * ret = w, and overwrite w with the result: trs(false, true, now.proposalInfo.qFactor, w); // compute the shrinkage factor t = g / (g + 1) const double g = exp(now.sample.z); //Previously used g directly, but if g=inf we need to use the limit // const double shrinkFactor = g / (g + 1.0); const double shrinkFactor = isinf(g) ? 1 : g / (g + 1.0); // scale the variance of the non-intercept coefficients // with this factor. // In the Cox case: no intercept present, so scale everything int startCoef = options.doGlm ? 1 : 0; w.rows(startCoef, w.n_rows - 1) *= sqrt(shrinkFactor); // also scale the mean of the non-intercept coefficients // appropriately: // In the Cox case: no intercept present, so scale everything now.sample.coefs = now.proposalInfo.coefs; now.sample.coefs.rows(startCoef, now.sample.coefs.n_rows - 1) *= shrinkFactor; // so altogether we have: now.sample.coefs += w; } ++nAccepted; } else // the generalized hyper-g prior case { // do 1 IWLS step, starting from the last linear predictor and the new z // (here the return value is not very interesting, as it must be 1) fitter.iwlsObject->startWithNewCoefs(1, exp(now.sample.z), now.sample.coefs); // get the results now.proposalInfo = fitter.iwlsObject->getResults(); // draw the proposal coefs: now.sample.coefs = drawNormalVector(now.proposalInfo.coefs, now.proposalInfo.qFactor); // compute the (unnormalized) log posterior of the proposal now.logUnPosterior = fitter.iwlsObject->computeLogUnPosteriorDens(now.sample); // ---------------------------------------------------------------------------------- // get the reverse jump normal density // ---------------------------------------------------------------------------------- // copy the old Mcmc object Mcmc reverse(old); // do again 1 IWLS step, starting from the sampled linear predictor and the old z fitter.iwlsObject->startWithNewCoefs(1, exp(reverse.sample.z), now.sample.coefs); // get the results for the reverse jump Gaussian: // only the proposal has changed in contrast to the old container, // the sample stays the same! reverse.proposalInfo = fitter.iwlsObject->getResults(); // ---------------------------------------------------------------------------------- // compute the proposal density ratio // ---------------------------------------------------------------------------------- // first the log of the numerator, i.e. log(f(old | new)): double logProposalRatioNumerator = reverse.computeLogProposalDens(); // second the log of the denominator, i.e. log(f(new | old)): double logProposalRatioDenominator = now.computeLogProposalDens(); // so the log proposal density ratio is double logProposalRatio = logProposalRatioNumerator - logProposalRatioDenominator; // ---------------------------------------------------------------------------------- // compute the posterior density ratio // ---------------------------------------------------------------------------------- double logPosteriorRatio = now.logUnPosterior - old.logUnPosterior; // ---------------------------------------------------------------------------------- // accept or reject proposal // ---------------------------------------------------------------------------------- double acceptanceProb = exp(logPosteriorRatio + logProposalRatio); if(unif() < acceptanceProb) { old = now; ++nAccepted; } else { now = old; } } // ---------------------------------------------------------------------------------- // store the sample? // ---------------------------------------------------------------------------------- // if the burnin was passed and we are at a multiple of step beyond that, then store // the sample. if((i_iter > options.burnin) && (((i_iter - options.burnin) % options.step) == 0)) { // echo debug-level message if(options.debug) { Rprintf("\ncpp_sampleGlm: Storing samples of iteration no. %d", i_iter); } // store the current parameter sample samples.storeParameters(now.sample); // ---------------------------------------------------------------------------------- // compute marginal likelihood terms // ---------------------------------------------------------------------------------- // compute marginal likelihood terms and save them? // (Note that the tbf bool is just for safety here, // the R function sampleGlm will set estimateMargLik to FALSE // when tbf is TRUE.) if(options.estimateMargLik && (! options.tbf)) { // echo debug-level message? if(options.debug) { Rprintf("\ncpp_sampleGlm: Compute marginal likelihood estimation terms"); } // ---------------------------------------------------------------------------------- // compute next term for the denominator // ---------------------------------------------------------------------------------- // draw from the high density point proposal distribution Mcmc denominator(highDensityPoint); denominator.sample.z = marginalZ.gen(1); fitter.iwlsObject->startWithNewLinPred(1, exp(denominator.sample.z), highDensityPoint.proposalInfo.linPred); denominator.proposalInfo = fitter.iwlsObject->getResults(); denominator.sample.coefs = drawNormalVector(denominator.proposalInfo.coefs, denominator.proposalInfo.qFactor); // get posterior density of the sample denominator.logUnPosterior = fitter.iwlsObject->computeLogUnPosteriorDens(denominator.sample); // get the proposal density at the sample double denominator_logProposalDensity = denominator.computeLogProposalDens(); // then the reverse stuff: // first we copy again the high density point Mcmc revDenom(highDensityPoint); // but choose the new sampled coefficients as starting point fitter.iwlsObject->startWithNewCoefs(1, exp(revDenom.sample.z), denominator.sample.coefs); revDenom.proposalInfo = fitter.iwlsObject->getResults(); // so the reverse proposal density is double revDenom_logProposalDensity = revDenom.computeLogProposalDens(); // so altogether the next term for the denominator is the following acceptance probability double denominatorTerm = denominator.logUnPosterior - highDensityPoint.logUnPosterior + revDenom_logProposalDensity - denominator_logProposalDensity; denominatorTerm = exp(fmin(0.0, denominatorTerm)); // ---------------------------------------------------------------------------------- // compute next term for the numerator // ---------------------------------------------------------------------------------- // compute the proposal density of the current sample starting from the high density point Mcmc numerator(now); fitter.iwlsObject->startWithNewLinPred(1, exp(numerator.sample.z), highDensityPoint.proposalInfo.linPred); numerator.proposalInfo = fitter.iwlsObject->getResults(); double numerator_logProposalDensity = numerator.computeLogProposalDens(); // then compute the reverse proposal density of the high density point when we start from the current // sample Mcmc revNum(highDensityPoint); fitter.iwlsObject->startWithNewCoefs(1, exp(revNum.sample.z), now.sample.coefs); revNum.proposalInfo = fitter.iwlsObject->getResults(); double revNum_logProposalDensity = revNum.computeLogProposalDens(); // so altogether the next term for the numerator is the following guy: double numeratorTerm = exp(fmin(revNum_logProposalDensity, highDensityPoint.logUnPosterior - now.logUnPosterior + numerator_logProposalDensity)); // ---------------------------------------------------------------------------------- // finally store both terms // ---------------------------------------------------------------------------------- samples.storeMargLikTerms(numeratorTerm, denominatorTerm); } } // ---------------------------------------------------------------------------------- // echo progress? // ---------------------------------------------------------------------------------- // echo debug-level message? if(options.debug) { Rprintf("\ncpp_sampleGlm: Finished iteration no. %d", i_iter); } if((i_iter % std::max(static_cast<int>(options.iterations / 100), 1) == 0) && options.verbose) { // display computation progress at each percent Rprintf("-"); } // end echo progress } // end MCMC loop // echo debug-level message? if(options.debug) { if(tbf) { Rprintf("\ncpp_sampleGlm: Finished MC simulation"); } else { Rprintf("\ncpp_sampleGlm: Finished MCMC loop"); } } // ---------------------------------------------------------------------------------- // build up return list for R and return that. // ---------------------------------------------------------------------------------- return List::create(_["samples"] = samples.convert2list(), _["nAccepted"] = nAccepted, _["highDensityPointLogUnPosterior"] = highDensityPoint.logUnPosterior); } // end cpp_sampleGlm