예제 #1
0
	/**
	 * @brief	Covariance matrix between the functional and derivative training data
	 *				or its partial derivative
	 *				given pair-wise squared distances and differences
	 * @param	[in] logHyp 				The log hyperparameters
	 *												- logHyp(0) = \f$\log(l)\f$
	 *												- logHyp(1) = \f$\log(\sigma_f)\f$
	 * @param	[in] pSqDist 				The pair-wise squared distances between the functional and derivative training data
	 * @param	[in] pDelta 				The pair-wise differences between the functional and derivative training data
	 * @param	[in] pdHypIndex			(Optional) Hyperparameter index for partial derivatives
	 * 											- pdHypIndex = -1: return \f$\frac{\partial \mathbf{K}(\mathbf{X}, \mathbf{Z})}{\partial \mathbf{Z}_j}\f$ (default)
	 *												- pdHypIndex =  0: return \f$\frac{\partial^2 \mathbf{K}(\mathbf{X}, \mathbf{Z})}{\partial \log(l) \partial \mathbf{Z}_j}\f$
	 *												- pdHypIndex =  1: return \f$\frac{\partial^2 \mathbf{K}(\mathbf{X}, \mathbf{Z})}{\partial \log(\sigma_f) \partial \mathbf{Z}_j}\f$
	 * @return	An NNxNN matrix pointer\n
	 * 			NN: The number of functional and derivative training data
	 */
	static MatrixPtr K_FD(const Hyp						&logHyp, 
								 const MatrixConstPtr		pSqDist, 
								 const MatrixConstPtr		pDelta, 
								 const int						pdHypIndex = -1)
	{
		// K: same size with the squared distances
		MatrixPtr pK = K(logHyp, pSqDist);

		// constants
		const Scalar inv_ell2 = exp(static_cast<Scalar>(-2.f) * logHyp(0));	// (1/ell^2)

		// pre-calculation
		// k(x, z) = sigma_f^2 * exp(-r^2/(2*ell^2)),	r = |x-z|
		// k(s)    = sigma_f^2 * exp(s),						s = -r^2/(2*ell^2)
		//
		// s = -r^2/(2*ell^2) = (-1/(2*ell^2)) * sum_{i=1}^d (xi - zi)^2
		// ds/dzj  = (xj - zj) / ell^2
		//
		// dk/ds		  = sigma_f^2 * exp(s) = k
		// dk(s)/dzj  = dk/ds * ds/dzj
		//            = k(x, z) * (xj - zj) / ell^2
		pK->noalias() = (inv_ell2 * pK->array() * pDelta->array()).matrix();

		// mode
		switch(pdHypIndex)
		{
		// derivatives of covariance matrix w.r.t log ell
		case 0:
			{
				// dk/dzj             = sigma_f^2 * exp(s) * (xj - zj) / ell^2
				// d^2k/dzj dlog(ell) = sigma_f^2 * exp(s) * [(xj - zj) / ell^2] * (r^2/ell^2 - 2)
				//                    = dk/dzj * (r^2/ell^2 - 2)
				pK->noalias() = (pK->array() * (inv_ell2 * (pSqDist->array()) - static_cast<Scalar>(2.f))).matrix();
				break;
			}

		// derivatives of covariance matrix w.r.t log sigma_f
		case 1:
			{
				// d^2k/dzj dlog(sigma_f) = 2 * dk/dzj
				pK->noalias() = static_cast<Scalar>(2.f) * (*pK);
				break;
			}
		// covariance matrix, dk/dzj
		default:
			{
				break;
			}
		}

		return pK;
	}
예제 #2
0
	/**
	 * @brief	Covariance matrix between the derivative training data
	 *				or its partial derivative
	 *				given pair-wise squared distances and differences
	 * @param	[in] logHyp 				The log hyperparameters
	 *												- logHyp(0) = \f$\log(l)\f$
	 *												- logHyp(1) = \f$\log(\sigma_f)\f$
	 * @param	[in] pSqDist 				The pair-wise squared distances between the functional and derivative training data
	 * @param	[in] pDelta_i 				The pair-wise differences of the i-th components between the functional and derivative training data
	 * @param	[in] pDelta_j 				The pair-wise differences of the j-th components between the functional and derivative training data
	 * @param	[in] fSameCoord 			i == j
	 * @param	[in] pdHypIndex			(Optional) Hyperparameter index for partial derivatives
	 * 											- pdHypIndex = -1: return \f$\frac{\partial^2 \mathbf{K}(\mathbf{X}, \mathbf{Z})}{\partial \mathbf{X}_i \partial \mathbf{Z}_j}\f$ (default)
	 *												- pdHypIndex =  0: return \f$\frac{\partial^3 \mathbf{K}(\mathbf{X}, \mathbf{Z})}{\partial \log(l) \partial \mathbf{X}_i \partial \mathbf{Z}_j}\f$
	 *												- pdHypIndex =  1: return \f$\frac{\partial^3 \mathbf{K}(\mathbf{X}, \mathbf{Z})}{\partial \log(\sigma_f) \partial \mathbf{X}_i \partial \mathbf{Z}_j}\f$
	 * @return	An NNxNN matrix pointer\n
	 * 			NN: The number of functional and derivative training data
	 */
	static MatrixPtr K_DD(const Hyp &logHyp, 
								 const MatrixConstPtr pSqDist, 
								 const MatrixConstPtr pDelta_i, 
								 const MatrixConstPtr pDelta_j,
								 const bool fSameCoord,
								 const int pdHypIndex = -1)
	{
		// K: same size with the squared distances
		MatrixPtr pK = K(logHyp, pSqDist, pdHypIndex);

		// hyperparameters
		const Scalar inv_ell2		= exp(static_cast<Scalar>(-2.f) * logHyp(0));	// 1/ell^2
		const Scalar inv_ell4		= inv_ell2 * inv_ell2;									// 1/ell^4
		const Scalar four_inv_ell4 = static_cast<Scalar>(4.f) * inv_ell4;				// 4/ell^4

		// delta
		const Scalar delta_inv_ell2 = fSameCoord ? inv_ell2 : static_cast<Scalar>(0.f);			// delta(i, j)/ell^2
		const Scalar neg_double_delta_inv_ell2 = static_cast<Scalar>(-2.f) * delta_inv_ell2;	// -2*delta(i, j)/ell^2

		// pre-calculation
		// k(x, z) = sigma_f^2 * exp(-r^2/(2*ell^2)),	r = |x-z|
		// k(s)    = sigma_f^2 * exp(s),						s = -r^2/(2*ell^2)
		//
		// s = -r^2/(2*ell^2) = (-1/(2*ell^2)) * sum_{i=1}^d (xi - zi)^2
		// ds/dzj  = (xj - zj) / ell^2
		//
		// dk/ds		  = sigma_f^2 * exp(s) = k
		// dk(s)/dzj  = dk/ds * ds/dzj
		//            = k(x, z) * (xj - zj) / ell^2
		//
		// d^2k/dzj dxi = dk/dxi						 * (xj - zj) / ell^2		+ k * delta(i, j) / ell^2
		//              = k * [-(xi - zi)/ell^2] * (xj - zj) / ell^2		+ k * delta(i, j) / ell^2
		//              = k * [delta(i, j)/ell^2 - (xi - zi)*(xj - zj)/ell^4]
		pK->noalias() = (pK->array() * (delta_inv_ell2 - inv_ell4 * pDelta_i->array() * pDelta_j->array())).matrix();
	
		// particularly, derivatives of covariance matrix w.r.t log ell
		if(pdHypIndex == 0)
		{
			// d^2k/dxi dzj           = k * [delta(i, j)/ell^2 - (xi - zi)*(xj - zj)/ell^4]
			// d^3k/dxi dzj dlog(ell) = dk/dlog(ell) * [delta(i, j)/ell^2 - (xi - zi)*(xj - zj)/ell^4]
			//                        + k * [-2*delta(i, j)/ell^2 + 4*(xi - zi)*(xj - zj)/ell^4]
			MatrixPtr pK0 = K(logHyp, pSqDist);
			pK->noalias() += (pK0->array() * (neg_double_delta_inv_ell2 + four_inv_ell4 * pDelta_i->array() * pDelta_j->array())).matrix();
		}

		return pK;
	}