8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use std:: os;
12
-
13
11
static PI : f64 = 3.141592653589793 ;
14
12
static SOLAR_MASS : f64 = 4.0 * PI * PI ;
15
13
static YEAR : f64 = 365.24 ;
@@ -18,151 +16,143 @@ static N_BODIES: uint = 5;
18
16
static BODIES : [ Planet , ..N_BODIES ] = [
19
17
// Sun
20
18
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 ,
23
21
mass : SOLAR_MASS ,
24
22
} ,
25
23
// Jupiter
26
24
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 ,
37
31
mass : 9.54791938424326609e-04 * SOLAR_MASS ,
38
32
} ,
39
33
// Saturn
40
34
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 ,
51
41
mass : 2.85885980666130812e-04 * SOLAR_MASS ,
52
42
} ,
53
43
// Uranus
54
44
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 ,
65
51
mass : 4.36624404335156298e-05 * SOLAR_MASS ,
66
52
} ,
67
53
// Neptune
68
54
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 ,
79
61
mass : 5.15138902046611451e-05 * SOLAR_MASS ,
80
62
} ,
81
63
] ;
82
64
83
65
struct Planet {
84
- x : [ f64 , .. 3 ] ,
85
- v : [ f64 , .. 3 ] ,
66
+ x : f64 , y : f64 , z : f64 ,
67
+ vx : f64 , vy : f64 , vz : f64 ,
86
68
mass : f64 ,
87
69
}
88
70
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 ) {
91
72
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
+ }
110
96
}
111
97
}
112
98
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 ;
117
103
}
118
104
}
119
105
}
120
106
121
107
fn energy ( bodies : & [ Planet , ..N_BODIES ] ) -> f64 {
122
108
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;
135
122
}
136
123
}
137
124
e
138
125
}
139
126
140
127
fn 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 ;
145
135
}
136
+ let sun = & mut bodies[ 0 ] ;
137
+ sun. vx = - px / SOLAR_MASS ;
138
+ sun. vy = - py / SOLAR_MASS ;
139
+ sun. vz = - pz / SOLAR_MASS ;
146
140
}
147
141
148
142
fn 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
154
145
} 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 )
156
149
} ;
157
-
158
- let n: i32 = from_str :: < i32 > ( * args. get ( 1 ) ) . unwrap ( ) ;
159
150
let mut bodies = BODIES ;
160
151
161
152
offset_momentum ( & mut bodies) ;
162
- println ! ( "{:.9f}" , energy( & bodies) as f64 ) ;
153
+ println ! ( "{:.9f}" , energy( & bodies) ) ;
163
154
164
155
advance ( & mut bodies, 0.01 , n) ;
165
156
166
- println ! ( "{:.9f}" , energy( & bodies) as f64 ) ;
157
+ println ! ( "{:.9f}" , energy( & bodies) ) ;
167
158
}
168
-
0 commit comments