diff --git a/elliptical/dw_elliptical.c b/elliptical/dw_elliptical.c index 9a0501db0de4a58c1798ade09ca938089fbab774..db80f84cc4e591e96353c33c8d7bd513db197630 100644 --- a/elliptical/dw_elliptical.c +++ b/elliptical/dw_elliptical.c @@ -153,7 +153,7 @@ static PRECISION draw_truncated_gaussian(PRECISION *draw, TElliptical *elliptica dw_NormalVector(elliptical->draw); while ((s=Norm(elliptical->draw)) == 0.0); r=sqrt(dw_chi_square_invcdf(d->cumulative_lower_bound + dw_uniform_rnd()*d->probability,elliptical->dim)); - ProductVS(elliptical->draw,elliptical->draw,r); + ProductVS(elliptical->draw,elliptical->draw,r/s); ProductMV(elliptical->draw,elliptical->scale,elliptical->draw); AddVV(elliptical->draw,elliptical->draw,elliptical->center); if (draw && (draw != pElementV(elliptical->draw))) @@ -169,19 +169,19 @@ static void print_info_truncated_gaussian(FILE *f_out, TElliptical *elliptical) } /* - Let z be a normal random vector with variance equal to scale*scale' and mean - equal to center. Truncate z so that it is on the elliptical annulus which is - given by the set of all z such that + Let z be a normal random vector with given center and variance. Truncate z so + that it is on the elliptical annulus given by the set of all z such that - r = sqrt((z - center)' * Inverse(scale * scale') * (z - center)) + r = sqrt((z - center)' * Inverse(variance) * (z - center)) - is between lower_bound and upper_bound. The density is given by + is between lower_bound and upper_bound. Choose scale so that variance=scale*scale'. + The density is given by Gamma(dim/2) f(r) --------------------------- ----------- 2 pi^(dim/2) |det(scale)| r^(dim-1) - The density of r is given by + where the density of r is given by r^(dim-1)*exp(-(r)^2/2) @@ -212,8 +212,7 @@ static void print_info_truncated_gaussian(FILE *f_out, TElliptical *elliptical) The GSL functions gsl_cdf_chisq_P() and gls_cdf_chisq_Pinv() are used to compute these functions. */ -TElliptical* CreateElliptical_TruncatedGaussian(int dim, TVector mean, TMatrix variance, - PRECISION lower_bound, PRECISION upper_bound) +TElliptical* CreateElliptical_TruncatedGaussian(int dim, TVector mean, TMatrix variance, PRECISION lower_bound, PRECISION upper_bound) { TElliptical* elliptical; TElliptical_gaussian *data; diff --git a/include/dw_elliptical.h b/include/dw_elliptical.h index d70316eed8b3b6fe4c3737ce292be3dd8a7c1674..e5a5663a1e3b19f1e9b66259a12d1fb3ea2e102a 100644 --- a/include/dw_elliptical.h +++ b/include/dw_elliptical.h @@ -126,7 +126,7 @@ This gives that the log of the density of z is given by -ln(abs(det(S)))-ln(2)-0.5*n*ln(pi)+ln(gamma(n/2))-(n-1)*ln(r)+ln(f(r)) -where r=norm(Inverse(S)*(z-c)). +where r=(z-c)'*Inverse(S*S')*(z-c). --------------------------------------------------------------------------------- Note that @@ -153,45 +153,5 @@ The mapping to the data structure is: quadratic_form = Inverse(S*S') logabsdet = -ln(abs(det(S))) dim = n - ---------------------------------------------------------------------------------- - -The truncated power case: - - Creates a power distribution on the elliptical annulus which is given by the - set of all z such that - - r = sqrt((z - center)' * Inverse(scale * scale') * (z - center)) - - is between lower_bound and upper_bound. The density is given by - - Gamma(dim/2) f(r) - --------------------------- ----------- - 2 pi^(dim/2) |det(scale)| r^(dim-1) - - where f(r) = power * r^(power-1) / (upper_bound^power - lower_bound^power) for - lower_bound <= r <= upper_bound and power > 0. - - Drawing z - The vector z can be obtained by drawing y from the standard dim-dimensional - Gaussian distribtuion, r from the distribution on [lower_bound,upper_bound] - with density f(r), and defining z = r*scale*(y/norm(y)) + center. - - Since the cumulative density of r is - - (r^power - lower_bound^k) / (upper_bound^power - lower_bound^power) - - a draw of r can be obtained by drawing u from the uniform on [0,1] and - defining by - - r = (multiplier*u + shift)^(1/power). - - where multiplier = (upper_bound^power - lower_bound^power) and - shift = lower_bound^power - - The variance_scale = sigma^2 * E[r^2] is - power*(upper_bound^(power+2) - lower_bound^(power+2)) - ------------------------------------------------------- - dim*(power+2)*(upper_bound^power - lower_bound^power) ********************************************************************************/