⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide.h

📁 使用R语言的马尔科夫链蒙特卡洛模拟(MCMC)源代码程序。
💻 H
📖 第 1 页 / 共 5 页
字号:
   * matrix to invert, ahead of time.   *   * \param A The symmetric positive definite matrix to invert.   * \param M The lower triangular matrix from the Cholesky decomposition of \a A.   *   * \see invpd(const Matrix<T, PO, PS>&)   * \see inv(const Matrix<T,PO1,PS1>&, const Matrix<T,PO2,PS2>&, const Matrix<T,PO3,PS3>&, const Matrix<unsigned int,PO4,PS4>&)   * \see inv(const Matrix<T, PO, PS>&)   * \see cholesky(const Matrix<T, PO, PS>&)   *   * \throw scythe_alloc_error (Level 1)   * \throw scythe_null_error (Level 1)   * \throw scythe_conformation_error (Level 1)   * \throw scythe_dimension_error (Level 1)   */  template <matrix_order RO, matrix_style RS, typename T,            matrix_order PO1, matrix_style PS1,            matrix_order PO2, matrix_style PS2>  Matrix<T,RO,RS>  invpd (const Matrix<T,PO1,PS1>& A, const Matrix<T,PO2,PS2>& M)  {    SCYTHE_CHECK_10(A.isNull(), scythe_null_error,        "A is NULL")    SCYTHE_CHECK_10(! A.isSquare(), scythe_dimension_error,        "A is not square")    SCYTHE_CHECK_10(A.rows() != M.cols() || A.cols() != M.rows(),         scythe_conformation_error, "A and M do not conform");          // for chol_solve block    T *y = new T[A.rows()];    T *x = new T[A.rows()];    Matrix<T, RO, Concrete> b(A.rows(), 1); // full of zeros    Matrix<T, RO, Concrete> null;        // For final answer    Matrix<T, RO, Concrete> Ainv(A.rows(), A.cols(), false);    for (uint k = 0; k < A.rows(); ++k) {      b[k] = (T) 1;      solve(M, null, b, x, y);      b[k] = (T) 0;      for (uint l = 0; l < A.rows(); ++l)        Ainv(l,k) = x[l];    }    delete[] y;    delete[] x;    SCYTHE_VIEW_RETURN(T, RO, RS, Ainv)  }  template <typename T, matrix_order PO1, matrix_style PS1,            matrix_order PO2, matrix_style PS2>  Matrix<T,PO1,Concrete>  invpd (const Matrix<T,PO1,PS1>& A, const Matrix<T,PO2,PS2>& M)  {    return invpd<PO1,Concrete>(A, M);  }  /*!\brief Calculate the inverse of a symmetric positive definite   * matrix.  *  * This function returns the inverse of a symmetric positive definite  * matrix, using cholesky() to do the necessary decomposition. This  * method is significantly faster than the generalized inverse  * function.  *  * \param A The symmetric positive definite matrix to invert.  *  * \see invpd(const Matrix<T, PO1, PS1>&, const Matrix<T, PO2, PS2>&)  * \see inv (const Matrix<T,PO1,PS1>&, const Matrix<T,PO2,PS2>&, const Matrix<T,PO3,PS3>&, const Matrix<unsigned int,PO4,PS4>&)  * \see inv (const Matrix<T, PO, PS>&)  *  * \throw scythe_alloc_error (Level 1)  * \throw scythe_null_error (Level 1)  * \throw scythe_conformation_error (Level 1)  * \throw scythe_dimension_error (Level 1)  * \throw scythe_type_error (Level 2)  */  template <matrix_order RO, matrix_style RS, typename T,            matrix_order PO, matrix_style PS>  Matrix<T, RO, RS>  invpd (const Matrix<T, PO, PS>& A)  {     // Cholesky checks to see if A is square and symmetric      return invpd<RO,RS>(A, cholesky<RO,Concrete>(A));  }  template <typename T, matrix_order O, matrix_style S>  Matrix<T, O, Concrete>  invpd (const Matrix<T,O,S>& A)  {    return invpd<O,Concrete>(A);  }  /* This code is based on  Algorithm 3.4.1 of Golub and Van Loan 3rd   * edition, 1996. Major difference is in how the output is   * structured.  Returns the sign of the row permutation (used by   * det).  Internal function, doesn't need doxygen.   */  namespace {    template <matrix_order PO1, matrix_style PS1, typename T,              matrix_order PO2, matrix_order PO3, matrix_order PO4>    inline T    lu_decomp_alg(Matrix<T,PO1,PS1>& A, Matrix<T,PO2,Concrete>& L,                   Matrix<T,PO3,Concrete>& U,                   Matrix<unsigned int, PO4, Concrete>& perm_vec)    {      if (A.isRowVector()) {        L = Matrix<T,PO2,Concrete> (1, 1, true, 1); // all 1s        U = A;        perm_vec = Matrix<uint, PO4, Concrete>(1, 1);  // all 0s        return (T) 0;      }            L = U = Matrix<T, PO2, Concrete>(A.rows(), A.cols(), false);      perm_vec = Matrix<uint, PO3, Concrete> (A.rows() - 1, 1, false);      uint pivot;      T temp;      T sign = (T) 1;      for (uint k = 0; k < A.rows() - 1; ++k) {        pivot = k;        // find pivot        for (uint i = k; i < A.rows(); ++i) {          if (std::fabs(A(pivot,k)) < std::fabs(A(i,k)))            pivot = i;        }                SCYTHE_CHECK_20(A(pivot,k) == (T) 0, scythe_type_error,            "Matrix is singular");        // permute        if (k != pivot) {          sign *= -1;          for (uint i = 0; i < A.rows(); ++i) {            temp = A(pivot,i);            A(pivot,i) = A(k,i);            A(k,i) = temp;          }        }        perm_vec[k] = pivot;        for (uint i = k + 1; i < A.rows(); ++i) {          A(i,k) = A(i,k) / A(k,k);          for (uint j = k + 1; j < A.rows(); ++j)            A(i,j) = A(i,j) - A(i,k) * A(k,j);        }      }      L = A;      for (uint i = 0; i < A.rows(); ++i) {        for (uint j = i; j < A.rows(); ++j) {          U(i,j) = A(i,j);          L(i,j) = (T) 0;          L(i,i) = (T) 1;        }      }      return sign;    }  }  /* Calculates the LU Decomposition of a square Matrix */  /* Note that the L, U, and perm_vec must be concrete. A is passed by   * value, because it is changed during the decomposition.  If A is a   * view, it will get mangled, but the decomposition will work fine.   * Not sure what the copy/view access trade-off is, but passing a   * view might speed things up if you don't care about messing up   * your matrix.   */    /*! \brief LU decomposition of a square matrix.     *     * This function performs LU decomposition. That is, given a     * non-singular square matrix \a A and three matrix references, \a     * L, \a U, and \a perm_vec, lu_decomp fills the latter three     * matrices such that \f$LU = A\f$. This method does not actually     * calculate the LU decomposition of \a A, but of a row-wise     * permutation of \a A. This permutation is recorded in perm_vec.     *     * \note Note that \a L, \a U, and \a perm_vec must be concrete.     * \a A is passed by value because the function modifies it during     * the decomposition.  Users should generally avoid passing Matrix     * views as the first argument to this function because this     * results in modification to the Matrix being viewed.     *     * \param A Non-singular square matrix to decompose.     * \param L Lower triangular portion of LU decomposition of A.     * \param U Upper triangular portion of LU decomposition of A.     * \param perm_vec Permutation vector recording the row-wise permutation of A actually decomposed by the algorithm.     *     * \see cholesky (const Matrix<T, PO, PS>&)     * \see lu_solve (const Matrix<T,PO1,PS1>&, const Matrix<T,PO2,PS2>&, const Matrix<T,PO3,PS3>&, const Matrix<T,PO4,PS4>&, const Matrix<unsigned int, PO5, PS5>&)     * \see lu_solve (Matrix<T,PO1,PS1>, const Matrix<T,PO2,PS2>&)     *     * \throw scythe_null_error (Level 1)     * \throw scythe_dimension_error (Level 1)     * \throw scythe_type_error (Level 2)     */  template <matrix_order PO1, matrix_style PS1, typename T,            matrix_order PO2, matrix_order PO3, matrix_order PO4>  void  lu_decomp(Matrix<T,PO1,PS1> A, Matrix<T,PO2,Concrete>& L,             Matrix<T,PO3,Concrete>& U,             Matrix<unsigned int, PO4, Concrete>& perm_vec)  {    SCYTHE_CHECK_10(A.isNull(), scythe_null_error,        "A is NULL")    SCYTHE_CHECK_10(! A.isSquare(), scythe_dimension_error,        "Matrix A not square");    lu_decomp_alg(A, L, U, perm_vec);  }  /* lu_solve overloaded: you need A, b + L, U, perm_vec from   * lu_decomp.   *   */    /*! \brief Solve \f$Ax=b\f$ for x via forward and backward     * substitution, given the results of a LU decomposition.     *     * This function solves the system of equations \f$Ax = b\f$ via     * forward and backward substitution and LU decomposition. \a A     * must be a non-singular square matrix for this method to work.     * This function requires the actual LU decomposition to be     * performed ahead of time; by lu_decomp() for example.     *     * This function is intended for repeatedly solving systems of     * equations based on \a A.  That is \a A stays constant while \a     * b varies.     *     * \param A Non-singular square Matrix to decompose, passed by reference.     * \param b Column vector with as many rows as \a A.     * \param L Lower triangular portion of LU decomposition of \a A.     * \param U Upper triangular portion of LU decomposition of \a A.     * \param perm_vec Permutation vector recording the row-wise permutation of \a A actually decomposed by the algorithm.     *     * \see lu_solve (Matrix<T,PO1,PS1>, const Matrix<T,PO2,PS2>&)     * \see lu_decomp(Matrix<T,PO1,PS1>, Matrix<T,PO2,Concrete>&, Matrix<T,PO3,Concrete>&, Matrix<unsigned int, PO4, Concrete>&)   * \see chol_solve(const Matrix<T,PO1,PS1> &, const Matrix<T,PO2,PS2> &)   * \see chol_solve(const Matrix<T,PO1,PS1> &, const Matrix<T,PO2,PS2> &, const Matrix<T,PO3,PS3> &)     *     * \throw scythe_null_error (Level 1)     * \throw scythe_dimension_error (Level 1)     * \throw scythe_conformation_error (Level 1)     */  template <matrix_order RO, matrix_style RS, typename T,            matrix_order PO1, matrix_style PS1,            matrix_order PO2, matrix_style PS2,            matrix_order PO3, matrix_style PS3,            matrix_order PO4, matrix_style PS4,            matrix_order PO5, matrix_style PS5>  Matrix<T, RO, RS>  lu_solve (const Matrix<T,PO1,PS1>& A, const Matrix<T,PO2,PS2>& b,            const Matrix<T,PO3,PS3>& L, const Matrix<T,PO4,PS4>& U,            const Matrix<unsigned int, PO5, PS5> &perm_vec)   {    SCYTHE_CHECK_10(A.isNull(), scythe_null_error,        "A is NULL")    SCYTHE_CHECK_10(! b.isColVector(), scythe_dimension_error,        "b is not a column vector");    SCYTHE_CHECK_10(! A.isSquare(), scythe_dimension_error,        "A is not square");    SCYTHE_CHECK_10(A.rows() != b.rows(), scythe_conformation_error,        "A and b have different row sizes");    SCYTHE_CHECK_10(A.rows() != L.rows() || A.rows() != U.rows() ||                    A.cols() != L.cols() || A.cols() != U.cols(),                    scythe_conformation_error,                    "A, L, and U do not conform");    SCYTHE_CHECK_10(perm_vec.rows() + 1 != A.rows(),        scythe_conformation_error,        "perm_vec does not have exactly one less row than A");    T *y = new T[A.rows()];    T *x = new T[A.rows()];        Matrix<T,RO,Concrete> bb = row_interchange(b, perm_vec);    solve(L, U, bb, x, y);    Matrix<T,RO,RS> result(A.rows(), 1, x);         delete[]x;    delete[]y;       return result;  }  template <typename T, matrix_order PO1, matrix_style PS1,            matrix_order PO2, matrix_style PS2,            matrix_order PO3, matrix_style PS3,            matrix_order PO4, matrix_style PS4,            matrix_order PO5, matrix_style PS5>  Matrix<T, PO1, Concrete>  lu_solve (const Matrix<T,PO1,PS1>& A, const Matrix<T,PO2,PS2>& b,            const Matrix<T,PO3,PS3>& L, const Matrix<T,PO4,PS4>& U,            const Matrix<unsigned int, PO5, PS5> &perm_vec)   {    return lu_solve<PO1,Concrete>(A, b, L, U, perm_vec);  }    /*! \brief Solve \f$Ax=b\f$ for x via forward and backward     * substitution, using LU decomposition      *     * This function solves the system of equations \f$Ax = b\f$ via     * forward and backward substitution and LU decomposition. \a A     * must be a non-singular square matrix for this method to work.     *     * \param A A non-singular square Matrix to decompose.     * \param b A column vector with as many rows as \a A.     *     * \see lu_solve (const Matrix<T,PO1,PS1>&, const Matrix<T,PO2,PS2>&, const Matrix<T,PO3,PS3>&, const Matrix<T,PO4,PS4>&, const Matrix<unsigned int, PO5, PS5>&)      * \see lu_decomp(Matrix<T,PO1,PS1>, Matrix<T,PO2,Concrete>&, Matrix<T,PO3,Concrete>&, Matrix<unsigned int, PO4, Concrete>&)   * \see chol_solve(const Matrix<T,PO1,PS1> &, const Matrix<T,PO2,PS2> &)   * \see chol_solve(const Matrix<T,PO1,PS1> &, const Matrix<T,PO2,PS2> &, const Matrix<T,PO3,PS3> &)   *     * \throw scythe_null_error (Level 1)     * \throw scythe_dimension_error (Level 1)     * \throw scythe_conformation_error (Level 1)     * \throw scythe_type_error (Level 2)     */  template <matrix_order RO, matrix_style RS, typename T,            matrix_order PO1, matrix_style PS1,            matrix_order PO2, matrix_style PS2>  Matrix<T,RO,RS>  lu_solve (Matrix<T,PO1,PS1> A, const Matrix<T,PO2,PS2>& b)  {    // step 1 compute the LU factorization     Matrix<T, RO, Concrete> L, U;    Matrix<uint, RO, Concrete> perm_vec;    lu_decomp_alg(A, L, U, perm_vec);    return lu_solve<RO,RS>(A, b, L, U, perm_vec);  }  template <typename T, matrix_order PO1, matrix_style PS1,            matrix_order PO2, matrix_style PS2>  Matrix<T,PO1,Concrete>  lu_solve (Matrix<T,PO1,PS1> A, const Matrix<T,PO2,PS2>& b)  {    // Slight code rep here, but very few lines       // step 1 compute the LU factorization     Matrix<T, PO1, Concrete> L, U;    Matrix<uint, PO1, Concrete> perm_vec;    lu_decomp_alg(A, L, U, perm_vec);        return lu_solve<PO1,Concrete>(A, b, L, U, perm_vec);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -