88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use std:: os;
12-
1311static PI : f64 = 3.141592653589793 ;
1412static SOLAR_MASS : f64 = 4.0 * PI * PI ;
1513static YEAR : f64 = 365.24 ;
@@ -18,151 +16,143 @@ static N_BODIES: uint = 5;
1816static BODIES : [ Planet , ..N_BODIES ] = [
1917 // Sun
2018 Planet {
21- x : [ 0.0 , 0.0 , 0.0 ] ,
22- v : [ 0.0 , 0.0 , 0.0 ] ,
19+ x : 0.0 , y : 0.0 , z : 0.0 ,
20+ vx : 0.0 , vy : 0.0 , vz : 0.0 ,
2321 mass : SOLAR_MASS ,
2422 } ,
2523 // Jupiter
2624 Planet {
27- x : [
28- 4.84143144246472090e+00 ,
29- -1.16032004402742839e+00 ,
30- -1.03622044471123109e-01 ,
31- ] ,
32- v : [
33- 1.66007664274403694e-03 * YEAR ,
34- 7.69901118419740425e-03 * YEAR ,
35- -6.90460016972063023e-05 * YEAR ,
36- ] ,
25+ x : 4.84143144246472090e+00 ,
26+ y : -1.16032004402742839e+00 ,
27+ z : -1.03622044471123109e-01 ,
28+ vx : 1.66007664274403694e-03 * YEAR ,
29+ vy : 7.69901118419740425e-03 * YEAR ,
30+ vz : -6.90460016972063023e-05 * YEAR ,
3731 mass : 9.54791938424326609e-04 * SOLAR_MASS ,
3832 } ,
3933 // Saturn
4034 Planet {
41- x : [
42- 8.34336671824457987e+00 ,
43- 4.12479856412430479e+00 ,
44- -4.03523417114321381e-01 ,
45- ] ,
46- v : [
47- -2.76742510726862411e-03 * YEAR ,
48- 4.99852801234917238e-03 * YEAR ,
49- 2.30417297573763929e-05 * YEAR ,
50- ] ,
35+ x : 8.34336671824457987e+00 ,
36+ y : 4.12479856412430479e+00 ,
37+ z : -4.03523417114321381e-01 ,
38+ vx : -2.76742510726862411e-03 * YEAR ,
39+ vy : 4.99852801234917238e-03 * YEAR ,
40+ vz : 2.30417297573763929e-05 * YEAR ,
5141 mass : 2.85885980666130812e-04 * SOLAR_MASS ,
5242 } ,
5343 // Uranus
5444 Planet {
55- x : [
56- 1.28943695621391310e+01 ,
57- -1.51111514016986312e+01 ,
58- -2.23307578892655734e-01 ,
59- ] ,
60- v : [
61- 2.96460137564761618e-03 * YEAR ,
62- 2.37847173959480950e-03 * YEAR ,
63- -2.96589568540237556e-05 * YEAR ,
64- ] ,
45+ x : 1.28943695621391310e+01 ,
46+ y : -1.51111514016986312e+01 ,
47+ z : -2.23307578892655734e-01 ,
48+ vx : 2.96460137564761618e-03 * YEAR ,
49+ vy : 2.37847173959480950e-03 * YEAR ,
50+ vz : -2.96589568540237556e-05 * YEAR ,
6551 mass : 4.36624404335156298e-05 * SOLAR_MASS ,
6652 } ,
6753 // Neptune
6854 Planet {
69- x : [
70- 1.53796971148509165e+01 ,
71- -2.59193146099879641e+01 ,
72- 1.79258772950371181e-01 ,
73- ] ,
74- v : [
75- 2.68067772490389322e-03 * YEAR ,
76- 1.62824170038242295e-03 * YEAR ,
77- -9.51592254519715870e-05 * YEAR ,
78- ] ,
55+ x : 1.53796971148509165e+01 ,
56+ y : -2.59193146099879641e+01 ,
57+ z : 1.79258772950371181e-01 ,
58+ vx : 2.68067772490389322e-03 * YEAR ,
59+ vy : 1.62824170038242295e-03 * YEAR ,
60+ vz : -9.51592254519715870e-05 * YEAR ,
7961 mass : 5.15138902046611451e-05 * SOLAR_MASS ,
8062 } ,
8163] ;
8264
8365struct Planet {
84- x : [ f64 , .. 3 ] ,
85- v : [ f64 , .. 3 ] ,
66+ x : f64 , y : f64 , z : f64 ,
67+ vx : f64 , vy : f64 , vz : f64 ,
8668 mass : f64 ,
8769}
8870
89- fn advance ( bodies : & mut [ Planet , ..N_BODIES ] , dt : f64 , steps : i32 ) {
90- let mut d = [ 0.0 , ..3 ] ;
71+ fn advance ( bodies : & mut [ Planet , ..N_BODIES ] , dt : f64 , steps : int ) {
9172 for _ in range ( 0 , steps) {
92- for i in range ( 0 u, N_BODIES ) {
93- for j in range ( i + 1 , N_BODIES ) {
94- d[ 0 ] = bodies[ i] . x [ 0 ] - bodies[ j] . x [ 0 ] ;
95- d[ 1 ] = bodies[ i] . x [ 1 ] - bodies[ j] . x [ 1 ] ;
96- d[ 2 ] = bodies[ i] . x [ 2 ] - bodies[ j] . x [ 2 ] ;
97-
98- let d2 = d[ 0 ] * d[ 0 ] + d[ 1 ] * d[ 1 ] + d[ 2 ] * d[ 2 ] ;
99- let mag = dt / ( d2 * d2. sqrt ( ) ) ;
100-
101- let a_mass = bodies[ i] . mass ;
102- let b_mass = bodies[ j] . mass ;
103- bodies[ i] . v [ 0 ] -= d[ 0 ] * b_mass * mag;
104- bodies[ i] . v [ 1 ] -= d[ 1 ] * b_mass * mag;
105- bodies[ i] . v [ 2 ] -= d[ 2 ] * b_mass * mag;
106-
107- bodies[ j] . v [ 0 ] += d[ 0 ] * a_mass * mag;
108- bodies[ j] . v [ 1 ] += d[ 1 ] * a_mass * mag;
109- bodies[ j] . v [ 2 ] += d[ 2 ] * a_mass * mag;
73+ {
74+ let mut b_slice = bodies. as_mut_slice ( ) ;
75+ loop {
76+ let bi = match b_slice. mut_shift_ref ( ) {
77+ Some ( bi) => bi,
78+ None => break
79+ } ;
80+ for bj in b_slice. mut_iter ( ) {
81+ let dx = bi. x - bj. x ;
82+ let dy = bi. y - bj. y ;
83+ let dz = bi. z - bj. z ;
84+
85+ let d2 = dx * dx + dy * dy + dz * dz;
86+ let mag = dt / ( d2 * d2. sqrt ( ) ) ;
87+
88+ bi. vx -= dx * bj. mass * mag;
89+ bi. vy -= dy * bj. mass * mag;
90+ bi. vz -= dz * bj. mass * mag;
91+
92+ bj. vx += dx * bi. mass * mag;
93+ bj. vy += dy * bi. mass * mag;
94+ bj. vz += dz * bi. mass * mag;
95+ }
11096 }
11197 }
11298
113- for a in bodies. mut_iter ( ) {
114- a . x [ 0 ] += dt * a . v [ 0 ] ;
115- a . x [ 1 ] += dt * a . v [ 1 ] ;
116- a . x [ 2 ] += dt * a . v [ 2 ] ;
99+ for bi in bodies. mut_iter ( ) {
100+ bi . x += dt * bi . vx ;
101+ bi . y += dt * bi . vy ;
102+ bi . z += dt * bi . vz ;
117103 }
118104 }
119105}
120106
121107fn energy ( bodies : & [ Planet , ..N_BODIES ] ) -> f64 {
122108 let mut e = 0.0 ;
123- let mut d = [ 0.0 , ..3 ] ;
124- for i in range ( 0 u, N_BODIES ) {
125- for k in range ( 0 u, 3 ) {
126- e += bodies[ i] . mass * bodies[ i] . v [ k] * bodies[ i] . v [ k] / 2.0 ;
127- }
128-
129- for j in range ( i + 1 , N_BODIES ) {
130- for k in range ( 0 u, 3 ) {
131- d[ k] = bodies[ i] . x [ k] - bodies[ j] . x [ k] ;
132- }
133- let dist = ( d[ 0 ] * d[ 0 ] + d[ 1 ] * d[ 1 ] + d[ 2 ] * d[ 2 ] ) . sqrt ( ) ;
134- e -= bodies[ i] . mass * bodies[ j] . mass / dist;
109+ let mut bodies = bodies. as_slice ( ) ;
110+ loop {
111+ let bi = match bodies. shift_ref ( ) {
112+ Some ( bi) => bi,
113+ None => break
114+ } ;
115+ e += ( bi. vx * bi. vx + bi. vy * bi. vy + bi. vz * bi. vz ) * bi. mass / 2.0 ;
116+ for bj in bodies. iter ( ) {
117+ let dx = bi. x - bj. x ;
118+ let dy = bi. y - bj. y ;
119+ let dz = bi. z - bj. z ;
120+ let dist = ( dx * dx + dy * dy + dz * dz) . sqrt ( ) ;
121+ e -= bi. mass * bj. mass / dist;
135122 }
136123 }
137124 e
138125}
139126
140127fn offset_momentum ( bodies : & mut [ Planet , ..N_BODIES ] ) {
141- for i in range( 0 u, N_BODIES ) {
142- for k in range( 0 u, 3 ) {
143- bodies[ 0 ] . v[ k] -= bodies[ i] . v[ k] * bodies[ i] . mass / SOLAR_MASS ;
144- }
128+ let mut px = 0 . 0 ;
129+ let mut py = 0.0 ;
130+ let mut pz = 0.0 ;
131+ for bi in bodies. iter ( ) {
132+ px += bi. vx * bi. mass ;
133+ py += bi. vy * bi. mass ;
134+ pz += bi. vz * bi. mass ;
145135 }
136+ let sun = & mut bodies[ 0 ] ;
137+ sun. vx = - px / SOLAR_MASS ;
138+ sun. vy = - py / SOLAR_MASS ;
139+ sun. vz = - pz / SOLAR_MASS ;
146140}
147141
148142fn main ( ) {
149- let args = os:: args ( ) ;
150- let args = if os:: getenv ( "RUST_BENCH" ) . is_some ( ) {
151- vec ! ( "" . to_owned( ) , "1000" . to_owned( ) )
152- } else if args. len ( ) <= 1 u {
153- vec ! ( "" . to_owned( ) , "1000" . to_owned( ) )
143+ let n = if std:: os:: getenv ( "RUST_BENCH" ) . is_some ( ) {
144+ 5000000
154145 } else {
155- args. move_iter ( ) . collect ( )
146+ std:: os:: args ( ) . as_slice ( ) . get ( 1 )
147+ . and_then ( |arg| from_str ( * arg) )
148+ . unwrap_or ( 1000 )
156149 } ;
157-
158- let n: i32 = from_str :: < i32 > ( * args. get ( 1 ) ) . unwrap ( ) ;
159150 let mut bodies = BODIES ;
160151
161152 offset_momentum ( & mut bodies) ;
162- println ! ( "{:.9f}" , energy( & bodies) as f64 ) ;
153+ println ! ( "{:.9f}" , energy( & bodies) ) ;
163154
164155 advance ( & mut bodies, 0.01 , n) ;
165156
166- println ! ( "{:.9f}" , energy( & bodies) as f64 ) ;
157+ println ! ( "{:.9f}" , energy( & bodies) ) ;
167158}
168-
0 commit comments