]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // The Computer Language Benchmarks Game |
2 | // http://benchmarksgame.alioth.debian.org/ | |
3 | // | |
4 | // contributed by the Rust Project Developers | |
5 | ||
6 | // Copyright (c) 2011-2014 The Rust Project Developers | |
7 | // | |
8 | // All rights reserved. | |
9 | // | |
10 | // Redistribution and use in source and binary forms, with or without | |
11 | // modification, are permitted provided that the following conditions | |
12 | // are met: | |
13 | // | |
14 | // - Redistributions of source code must retain the above copyright | |
15 | // notice, this list of conditions and the following disclaimer. | |
16 | // | |
17 | // - Redistributions in binary form must reproduce the above copyright | |
18 | // notice, this list of conditions and the following disclaimer in | |
19 | // the documentation and/or other materials provided with the | |
20 | // distribution. | |
21 | // | |
22 | // - Neither the name of "The Computer Language Benchmarks Game" nor | |
23 | // the name of "The Computer Language Shootout Benchmarks" nor the | |
24 | // names of its contributors may be used to endorse or promote | |
25 | // products derived from this software without specific prior | |
26 | // written permission. | |
27 | // | |
28 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
29 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
30 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
31 | // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
32 | // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
33 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
34 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
35 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
36 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
37 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
38 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
39 | // OF THE POSSIBILITY OF SUCH DAMAGE. | |
40 | ||
9346a6ac | 41 | use std::mem; |
1a4d82fc JJ |
42 | |
43 | const PI: f64 = 3.141592653589793; | |
44 | const SOLAR_MASS: f64 = 4.0 * PI * PI; | |
45 | const YEAR: f64 = 365.24; | |
c34b1796 | 46 | const N_BODIES: usize = 5; |
1a4d82fc JJ |
47 | |
48 | static BODIES: [Planet;N_BODIES] = [ | |
970d7e83 LB |
49 | // Sun |
50 | Planet { | |
1a4d82fc JJ |
51 | x: 0.0, y: 0.0, z: 0.0, |
52 | vx: 0.0, vy: 0.0, vz: 0.0, | |
970d7e83 LB |
53 | mass: SOLAR_MASS, |
54 | }, | |
55 | // Jupiter | |
56 | Planet { | |
1a4d82fc JJ |
57 | x: 4.84143144246472090e+00, |
58 | y: -1.16032004402742839e+00, | |
59 | z: -1.03622044471123109e-01, | |
60 | vx: 1.66007664274403694e-03 * YEAR, | |
61 | vy: 7.69901118419740425e-03 * YEAR, | |
62 | vz: -6.90460016972063023e-05 * YEAR, | |
970d7e83 LB |
63 | mass: 9.54791938424326609e-04 * SOLAR_MASS, |
64 | }, | |
65 | // Saturn | |
66 | Planet { | |
1a4d82fc JJ |
67 | x: 8.34336671824457987e+00, |
68 | y: 4.12479856412430479e+00, | |
69 | z: -4.03523417114321381e-01, | |
70 | vx: -2.76742510726862411e-03 * YEAR, | |
71 | vy: 4.99852801234917238e-03 * YEAR, | |
72 | vz: 2.30417297573763929e-05 * YEAR, | |
970d7e83 LB |
73 | mass: 2.85885980666130812e-04 * SOLAR_MASS, |
74 | }, | |
75 | // Uranus | |
76 | Planet { | |
1a4d82fc JJ |
77 | x: 1.28943695621391310e+01, |
78 | y: -1.51111514016986312e+01, | |
79 | z: -2.23307578892655734e-01, | |
80 | vx: 2.96460137564761618e-03 * YEAR, | |
81 | vy: 2.37847173959480950e-03 * YEAR, | |
82 | vz: -2.96589568540237556e-05 * YEAR, | |
970d7e83 LB |
83 | mass: 4.36624404335156298e-05 * SOLAR_MASS, |
84 | }, | |
85 | // Neptune | |
86 | Planet { | |
1a4d82fc JJ |
87 | x: 1.53796971148509165e+01, |
88 | y: -2.59193146099879641e+01, | |
89 | z: 1.79258772950371181e-01, | |
90 | vx: 2.68067772490389322e-03 * YEAR, | |
91 | vy: 1.62824170038242295e-03 * YEAR, | |
92 | vz: -9.51592254519715870e-05 * YEAR, | |
970d7e83 LB |
93 | mass: 5.15138902046611451e-05 * SOLAR_MASS, |
94 | }, | |
95 | ]; | |
96 | ||
c34b1796 | 97 | #[derive(Copy, Clone)] |
970d7e83 | 98 | struct Planet { |
1a4d82fc JJ |
99 | x: f64, y: f64, z: f64, |
100 | vx: f64, vy: f64, vz: f64, | |
970d7e83 | 101 | mass: f64, |
223e47cc LB |
102 | } |
103 | ||
c34b1796 | 104 | fn advance(bodies: &mut [Planet;N_BODIES], dt: f64, steps: isize) { |
85aaf69f SL |
105 | for _ in 0..steps { |
106 | let mut b_slice: &mut [_] = bodies; | |
1a4d82fc JJ |
107 | loop { |
108 | let bi = match shift_mut_ref(&mut b_slice) { | |
109 | Some(bi) => bi, | |
110 | None => break | |
111 | }; | |
85aaf69f | 112 | for bj in &mut *b_slice { |
1a4d82fc JJ |
113 | let dx = bi.x - bj.x; |
114 | let dy = bi.y - bj.y; | |
115 | let dz = bi.z - bj.z; | |
116 | ||
117 | let d2 = dx * dx + dy * dy + dz * dz; | |
118 | let mag = dt / (d2 * d2.sqrt()); | |
119 | ||
120 | let massj_mag = bj.mass * mag; | |
121 | bi.vx -= dx * massj_mag; | |
122 | bi.vy -= dy * massj_mag; | |
123 | bi.vz -= dz * massj_mag; | |
223e47cc | 124 | |
1a4d82fc JJ |
125 | let massi_mag = bi.mass * mag; |
126 | bj.vx += dx * massi_mag; | |
127 | bj.vy += dy * massi_mag; | |
128 | bj.vz += dz * massi_mag; | |
129 | } | |
130 | bi.x += dt * bi.vx; | |
131 | bi.y += dt * bi.vy; | |
132 | bi.z += dt * bi.vz; | |
223e47cc LB |
133 | } |
134 | } | |
970d7e83 | 135 | } |
223e47cc | 136 | |
1a4d82fc | 137 | fn energy(bodies: &[Planet;N_BODIES]) -> f64 { |
970d7e83 | 138 | let mut e = 0.0; |
1a4d82fc JJ |
139 | let mut bodies = bodies.iter(); |
140 | loop { | |
141 | let bi = match bodies.next() { | |
142 | Some(bi) => bi, | |
143 | None => break | |
144 | }; | |
145 | e += (bi.vx * bi.vx + bi.vy * bi.vy + bi.vz * bi.vz) * bi.mass / 2.0; | |
146 | for bj in bodies.clone() { | |
147 | let dx = bi.x - bj.x; | |
148 | let dy = bi.y - bj.y; | |
149 | let dz = bi.z - bj.z; | |
150 | let dist = (dx * dx + dy * dy + dz * dz).sqrt(); | |
151 | e -= bi.mass * bj.mass / dist; | |
223e47cc LB |
152 | } |
153 | } | |
970d7e83 | 154 | e |
223e47cc LB |
155 | } |
156 | ||
1a4d82fc JJ |
157 | fn offset_momentum(bodies: &mut [Planet;N_BODIES]) { |
158 | let mut px = 0.0; | |
159 | let mut py = 0.0; | |
160 | let mut pz = 0.0; | |
62682a34 | 161 | for bi in bodies.iter() { |
1a4d82fc JJ |
162 | px += bi.vx * bi.mass; |
163 | py += bi.vy * bi.mass; | |
164 | pz += bi.vz * bi.mass; | |
223e47cc | 165 | } |
1a4d82fc JJ |
166 | let sun = &mut bodies[0]; |
167 | sun.vx = - px / SOLAR_MASS; | |
168 | sun.vy = - py / SOLAR_MASS; | |
169 | sun.vz = - pz / SOLAR_MASS; | |
970d7e83 | 170 | } |
223e47cc | 171 | |
970d7e83 | 172 | fn main() { |
85aaf69f | 173 | let n = if std::env::var_os("RUST_BENCH").is_some() { |
1a4d82fc JJ |
174 | 5000000 |
175 | } else { | |
85aaf69f SL |
176 | std::env::args().nth(1) |
177 | .and_then(|arg| arg.parse().ok()) | |
1a4d82fc JJ |
178 | .unwrap_or(1000) |
179 | }; | |
970d7e83 | 180 | let mut bodies = BODIES; |
223e47cc | 181 | |
970d7e83 | 182 | offset_momentum(&mut bodies); |
1a4d82fc | 183 | println!("{:.9}", energy(&bodies)); |
223e47cc | 184 | |
970d7e83 | 185 | advance(&mut bodies, 0.01, n); |
223e47cc | 186 | |
1a4d82fc JJ |
187 | println!("{:.9}", energy(&bodies)); |
188 | } | |
189 | ||
190 | /// Pop a mutable reference off the head of a slice, mutating the slice to no | |
191 | /// longer contain the mutable reference. This is a safe operation because the | |
192 | /// two mutable borrows are entirely disjoint. | |
193 | fn shift_mut_ref<'a, T>(r: &mut &'a mut [T]) -> Option<&'a mut T> { | |
9346a6ac AL |
194 | let res = mem::replace(r, &mut []); |
195 | if res.is_empty() { return None } | |
196 | let (a, b) = res.split_at_mut(1); | |
197 | *r = b; | |
198 | Some(&mut a[0]) | |
223e47cc | 199 | } |