123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #|
- The Computer Language Benchmarks Game
- http://shootout.alioth.debian.org/
- Contributed by Per Bothner
- Based on Java version contributed by Mark C. Lewis,
- modified slightly by Chad Whipkey.
- |#
- (define-syntax square
- (syntax-rules ()
- ((square x)
- (let ((tmp x)) (* tmp tmp)))))
- (define-syntax increment
- (syntax-rules ()
- ((increment lhs rhs)
- (set! lhs (+ lhs rhs)))))
- (define-syntax decrement
- (syntax-rules ()
- ((increment lhs rhs)
- (set! lhs (- lhs rhs)))))
- (define-constant PI :: double 3.141592653589793)
- (define-constant SOLAR_MASS :: double (* 4 PI PI))
- (define-constant DAYS_PER_YEAR :: double 365.24)
- (define-class Body ()
- (x :: double)
- (y :: double)
- (z :: double)
- (vx :: double)
- (vy :: double)
- (vz :: double)
- (mass :: double)
- ((offsetMomentum (px :: double) (py :: double) (pz :: double)) :: void
- (set! vx (/ (- px) SOLAR_MASS))
- (set! vy (/ (- py) SOLAR_MASS))
- (set! vz (/ (- pz) SOLAR_MASS))))
- (define (nbody-system (n :: int)) :: void
- (let* ((bodies (Body[] (sun) (jupiter) (saturn) (uranus) (neptune)))
- (px :: double 0)
- (py :: double 0)
- (pz :: double 0)
- (nbodies :: int bodies:length))
- (do ((i :: int 0 (+ i 1))) ((>= i nbodies))
- (let* ((ibody (bodies i))
- (imass ibody:mass))
- (increment px (* ibody:vx imass))
- (increment py (* ibody:vy imass))
- (increment pz (* ibody:vz imass))))
- ((bodies 0):offsetMomentum px py pz)
- (format #t "~,9f~%" (energy bodies))
- (do ((i :: int 0 (+ i 1))) ((>= i n))
- (advance bodies 0.01))
- (format #t "~,9f~%" (energy bodies))))
- (define (advance (bodies ::Body[]) (dt ::double)) :: void
- (let ((nbodies bodies:length))
- (do ((i ::int 0 (+ i 1))) ((>= i nbodies))
- (! ibody (bodies i))
- (do ((j ::int (+ i 1) (+ j 1))) ((>= j nbodies))
- (! jbody (bodies j))
- (! dx (- ibody:x jbody:x))
- (! dy (- ibody:y jbody:y))
- (! dz (- ibody:z jbody:z))
- (! dsquared (+ (square dx) (square dy) (square dz)))
- (! distance (java.lang.Math:sqrt dsquared))
- (! mag (/ dt (* dsquared distance)))
- (decrement ibody:vx (* dx jbody:mass mag))
- (decrement ibody:vy (* dy jbody:mass mag))
- (decrement ibody:vz (* dz jbody:mass mag))
- (increment jbody:vx (* dx ibody:mass mag))
- (increment jbody:vy (* dy ibody:mass mag))
- (increment jbody:vz (* dz ibody:mass mag))))
- (do ((i ::int 0 (+ i 1))) ((>= i nbodies))
- (! body (bodies i))
- (increment body:x (* dt body:vx))
- (increment body:y (* dt body:vy))
- (increment body:z (* dt body:vz)))))
- (define (energy (bodies ::Body[])) :: double
- ;; should be something like 'defvar'
- ;; Maybe: (! e ::double init: 0)
- (define e ::double 0)
- (! nbodies bodies:length)
- (do ((i ::int 0 (+ i 1))) ((>= i nbodies))
- (! ibody (bodies i))
- (increment e (* 0.5 ibody:mass
- (+ (square ibody:vx)
- (square ibody:vy)
- (square ibody:vz))))
- (do ((j ::int (+ i 1) (+ j 1))) ((>= j nbodies))
- (! jbody (bodies j))
- (! dx (- ibody:x jbody:x))
- (! dy (- ibody:y jbody:y))
- (! dz (- ibody:z jbody:z))
- (! distance (java.lang.Math:sqrt (+ (square dx) (square dy) (square dz))))
- (decrement e (/ (* ibody:mass jbody:mass) distance))))
- e)
- (define (jupiter) :: Body
- (Body x: 4.84143144246472090e+00
- y: -1.16032004402742839e+00
- z: -1.03622044471123109e-01
- vx: (* 1.66007664274403694e-03 DAYS_PER_YEAR)
- vy: (* 7.69901118419740425e-03 DAYS_PER_YEAR)
- vz: (* -6.90460016972063023e-05 DAYS_PER_YEAR)
- mass: (* 9.54791938424326609e-04 SOLAR_MASS)))
- (define (saturn) :: Body
- (Body x: 8.34336671824457987e+00
- y: 4.12479856412430479e+00
- z: -4.03523417114321381e-01
- vx: (* -2.76742510726862411e-03 DAYS_PER_YEAR)
- vy: (* 4.99852801234917238e-03 DAYS_PER_YEAR)
- vz: (* 2.30417297573763929e-05 DAYS_PER_YEAR)
- mass: (* 2.85885980666130812e-04 SOLAR_MASS)))
- (define (uranus) :: Body
- (Body x: 1.28943695621391310e+01
- y: -1.51111514016986312e+01
- z: -2.23307578892655734e-01
- vx: (* 2.96460137564761618e-03 DAYS_PER_YEAR)
- vy: (* 2.37847173959480950e-03 DAYS_PER_YEAR)
- vz: (* -2.96589568540237556e-05 DAYS_PER_YEAR)
- mass: (* 4.36624404335156298e-05 SOLAR_MASS)))
- (define (neptune) :: Body
- (Body x: 1.53796971148509165e+01
- y: -2.59193146099879641e+01
- z: 1.79258772950371181e-01
- vx: (* 2.68067772490389322e-03 DAYS_PER_YEAR)
- vy: (* 1.62824170038242295e-03 DAYS_PER_YEAR)
- vz: (* -9.51592254519715870e-05 DAYS_PER_YEAR)
- mass: (* 5.15138902046611451e-05 SOLAR_MASS)))
- (define (sun) :: Body
- (Body mass: SOLAR_MASS))
- (nbody-system (string->number (cadr (command-line))))
|