(sc-include "macros/macros") (pre-include "gsl/gsl_poly.h") (pre-include "gsl/gsl_sf.h") (pre-include "extent-sampling.h") (pre-include "oracles.h") (pre-include "integrands.h") (pre-include "utils.h") (pre-define TRIALS 1000) (pre-define MAX-EXTENT 1.0) (sc-define-syntax* (define-polynomial var) (let ((coefficients (list -0.09375 0.6875 -1.5 1)) (coeff (sc-gensym))) `(begin (declare ,coeff (array double ,(length coefficients))) (array-set* ,coeff ,@coefficients) (declare ,var (struct-variable polynomial-integrand-params (coefficients ,coeff) (degree ,(1- (length coefficients)))))))) (sc-define-syntax (polynomial-map! polynomial i coeff form) (for-i i (+ 1 (struct-get polynomial degree)) (let* ((coeff double (array-get (struct-get polynomial coefficients) i))) (array-set (convert-type (struct-get polynomial coefficients) double*) i form)))) (define (polyval polynomial value) (double polynomial-integrand-params double) (return (gsl-poly-eval (struct-get polynomial coefficients) (+ 1 (struct-get polynomial degree)) value))) (sc-define-syntax* (define-polynomial-integrand integrand) (let ((params (sc-gensym))) `(begin (define-polynomial ,params) (declare ,integrand (struct-variable (const integrand-t) (integrand polynomial-integrand) (params (address-of ,params))))))) (sc-define-syntax* (define-uniform-extent-oracle oracle a b) (let ((oracle-params (sc-gensym))) `(begin (declare ,oracle-params (struct-variable uniform-params (a ,a) (b ,b))) (declare ,oracle (struct-variable extent-oracle-t (oracle uniform-extent-oracle) (params (address-of ,oracle-params))))))) (sc-define-syntax* (experiment integrand true-integral filename) (let ((rtols (list 0.2 0.1 0.05))) `(begin ,@(map (lambda (i rtol) `(begin (with-data-file fp ,(format #f "integral-~a-~a.dat" filename rtol) "w" (fprintf fp "dimension\tsamples\n")))) (iota (length rtols)) rtols) (for-i-step dimension 10 100 10 (printf "Dimension %d: " dimension) (with-rstats* samples ,(length rtols) (for-i trial TRIALS (with-rstats stats ,@(map (lambda (i rtol) `(begin (integral (address-of ,integrand) (address-of oracle) (,true-integral dimension) rng dimension ,rtol stats) (gsl-rstat-add (gsl-rstat-n stats) (array-get samples ,i)))) (iota (length rtols)) rtols)) (when (= (modulo trial (/ TRIALS 10)) 0) (printf "%d " trial)) (fflush NULL)) (printf "\n") ,@(map (lambda (i rtol) `(with-data-file fp ,(format #f "integral-~a-~a.dat" filename rtol) "a" (fprintf fp "%d\t%g\n" dimension (gsl-rstat-mean (array-get samples ,i))))) (iota (length rtols)) rtols)))))) (define (true-polynomial-integral dimension) (double (unsigned int)) (define-polynomial polynomial) (polynomial-map! polynomial k coeff (/ coeff (+ dimension k) (+ dimension k 1))) (return (* (surface-area-of-ball dimension) (gsl-pow-uint MAX-EXTENT dimension) (polyval polynomial MAX-EXTENT)))) (define (lower-incomplete-gamma s x) (double double double) (return (* (gsl-sf-gamma s) (gsl-sf-gamma-inc-P s x)))) (define (true-gaussian-integral dimension) (double (unsigned int)) (return (/ (* (pow 2.0 (- (* dimension 0.5) 1)) (surface-area-of-ball dimension) (- (* MAX-EXTENT (lower-incomplete-gamma (* 0.5 dimension) (* 0.5 (gsl-pow-2 MAX-EXTENT)))) (* (sqrt 2.0) (lower-incomplete-gamma (* 0.5 (+ dimension 1)) (* 0.5 (gsl-pow-2 MAX-EXTENT)))))) MAX-EXTENT))) (define (true-x-coordinate-integral dimension) (double (unsigned int)) (return (/ (* (gsl-pow-uint MAX-EXTENT (1+ dimension)) (surface-area-of-ball (+ dimension 3))) 2.0 (pow M-PI 2) (+ dimension 2)))) (define (main) (int) (define-polynomial-integrand -polynomial-integrand) (declare -gaussian-integrand (struct-variable (const integrand-t) gaussian-integrand NULL)) (declare -x-coordinate-integrand (struct-variable (const integrand-t) x-coordinate-integrand NULL)) (define-uniform-extent-oracle oracle 0 MAX-EXTENT) (with-rng rng (experiment -polynomial-integrand true-polynomial-integral "polynomial") (experiment -gaussian-integrand true-gaussian-integral "gaussian") (experiment -x-coordinate-integrand true-x-coordinate-integral "x-coordinate")) (with-data-file fp "integral-parameters.tex" "w" (fprintf fp "\\\\newcommand{\\\\integraltrials}{%d}\n" TRIALS)) (return 0))