/******************************************************************************** * * Bayesian Regression and Adaptive Sampling with Gaussian Process Trees * Copyright (C) 2005, University of California * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Questions? Contact Robert B. Gramacy (rbgramacy@ams.ucsc.edu) * ********************************************************************************/ #include #include #include #include #include #include "rand_pdf.h" #include "matrix.h" #include "linalg.h" #include "rhelp.h" #define DEBUG /* * copyCovUpper: * * copy the upper trianglar part of (n x n) Sigma into cov * so that cov can be an argument to LAPACK (like Choleski * decomposition) routines which modify their argument */ void copyCovUpper(cov, Sigma, n, scale) unsigned int n; /*double cov[][n], Sigma[][n];*/ double **cov, **Sigma; double scale; { int i,j; for(i=0; i0 && b>0); /* evaluate the pdf for each x */ for(i=0; i 0); p[i] = a*log(b) - lgammafn(a) + (a-1)*log(x[i]) - b*x[i]; } } /* * invgampdf_log_gelman: * * GELMAN PARAMATERIZATION * logarithm of the density of n x values distributed * as Gamma(a,b). * p must be pre-alloc'd n-array */ void invgampdf_log_gelman(p, x, a, b, n) unsigned int n; double *p, *x, a, b; { int i; /* sanity checks */ assert(a>0 && b>0); /* evaluate the pdf for each x */ for(i=0; i= 0); p[i] = a*log(b) - lgammafn(a) - (a+1)*log(x[i]) - b/x[i]; } } /* * gampdf_log: * * logarithm of the density of n x values distributed * as Gamma(a,b). * p must be pre-alloc'd n-array; not using Gelman parameterization */ void gampdf_log(p, x, a, b, n) unsigned int n; double *p, *x, a, b; { int i; /* sanity checks */ assert(a>0 && b>0); /* evaluate the pdf for each x */ for(i=0; i 0); p[i] = - a*log(b) - lgammafn(a) + (a-1)*log(x[i]) - x[i]/b; } } /* * betapdf_log: * * logarithm of the density of n x values distributed * as Beta(a,b). * p must be pre-alloc'd n-array */ void betapdf_log(p, x, a, b, n) unsigned int n; double *p, *x, a, b; { int i; for(i=0; i 0); assert(nu > n); /* denominator */ /* gammapart <- 1 */ lgampart = 0.0; /* for(i in 1:k) gammapart <- gammapart * gamma((v + 1 - i)/2) */ for(i=1; i<=n; i++) lgampart += lgammafn((nu+1.0-(double)i)/2.0 ); /* denom <- gammapart * 2^(v * k / 2) * pi^(k*(k-1)/4) */ denom = lgampart + (nu*n/2.0)*M_LN2 + (n*(n-1.0)/2.0)*M_LN_SQRT_PI; /* numerator */ /* detW <- det(W) */ ldetW = log_determinant_dup(x, n); /* hold <- solve(S) %*% W */ hold = new_dup_matrix(x, n, n); Sdup = new_dup_matrix(S, n, n); linalg_dposv(n, Sdup, hold); /* detS <- det(S) */ /* dposv should have left us with chol(S) inside Sdup */ ldetS = log_determinant_chol(Sdup, n); /* tracehold <- sum(hold[row(hold) == col(hold)]) */ tracehold = 0.0; for(i=0; i 0); assert(*nu_in > *n_in); /* copy W_in vector to W matrix */ /* Bobby: this is wasteful; should write a function which allocates * the "skeleton" of a new matrix, and points W[0] to a vector */ W = new_matrix(*n_in, *n_in); dupv(W[0], W_in, *n_in * *n_in); /* copy S_in vector to S matrix */ S = new_matrix(*n_in, *n_in); dupv(S[0], S_in, *n_in * *n_in); /* evaluate the lpdf */ *lpdf_out = wishpdf_log(W, S, *n_in, *nu_in); /* clean up */ delete_matrix(W); delete_matrix(S); } /* * temper: * * apply temperature temp to pdf density p; i.e., * take p^temp when uselog = 0, and temp*k, when * uselog = 1, assuming that p is in log space */ double temper(double p, double temp, int uselog) { double tp; /* remove this later */ if(temp != 1.0) warning("temper(): temp = %g is not 1.0", temp); if(uselog) tp = temp * p; else { if(temp == 1.0) tp = p; else if(temp == 0.0) tp = 1.0; else tp = pow(p, temp); } return tp; } /* * temper_invgam: * * apply temperature t to the alpha (a) and beta (b) parameters * to the inverse gamma distribution */ void temper_invgam(double *a, double *b, double temp) { /* remove this later */ if(temp != 1.0) warning("temper_invgam(): temp = %g is not 1.0", temp); *a = temp*(*a+1.0) - 1.0; *b = temp * (*b); /* sanity check */ assert(*a > 0 && *b > 0); }