Wiki

RunTimePerformance: cobra_nbody.cobra

File cobra_nbody.cobra, 6.0 KB (added by torial, 9 months ago)

Optimized cobra version

Line 
1# The Computer Language Benchmarks Game
2# http://shootout.alioth.debian.org/
3#
4# originally by Kevin Carson
5# modified by Tupteq, Fredrik Johansson, and Daniel Nanz
6# modified by Maciej Fijalkowski
7# 2to3
8@number float
9class Triple
10    var x as float 
11    var y as float 
12    var z as float
13    #pro x from var as float
14    #pro y from var as float
15    #pro z from var as float
16    get squared as float
17        return .x*.x + .y*.y + .z*.z
18   
19    cue init(x as float, y as float, z as float)
20        base.init
21        .x = x
22        .y = y
23        .z = z
24       
25    def toString as String is override
26        return "\[[.x], [.y], [.z]\]"
27
28class Body
29    var coord as Triple
30    var velocity as Triple
31    var mass as float
32    #pro coord from var as Triple
33    #pro velocity from var as Triple
34    #pro mass from var as float
35   
36    cue init(coord as Triple, velocity as Triple, mass as float)
37        base.init
38        .coord = coord
39        .velocity = velocity
40        .mass = mass 
41
42    def updateCoordinates(dt as float)
43        .coord.x += dt * .velocity.x
44        .coord.y += dt * .velocity.y
45        .coord.z += dt * .velocity.z
46
47       
48class BodyPair
49    var body1 as Body
50    var body2 as Body 
51    #pro body1 from var as Body
52    #pro body2 from var as Body 
53   
54    cue init(body1 as Body, body2 as Body)
55        base.init
56        .body1 = body1
57        .body2 = body2
58
59class Program
60    def combinations(l) as List<of BodyPair>
61        result = List<of BodyPair>()
62        for x in l.count - 1
63            ls = l[x+1:]
64            for y in ls
65                result.add(BodyPair(l[x],y))
66        return result
67
68    cue init
69        base.init
70   
71        bodies as Dictionary<of String, Body> = {
72            'sun': Body(Triple(0.0, 0.0, 0.0), Triple(0.0, 0.0, 0.0), .sOLAR_MASS),
73
74            'jupiter': Body(Triple(4.84143144246472090,
75                -1.16032004402742839,
76                -0.103622044471123109),
77                Triple(0.00166007664274403694 * .dAYS_PER_YEAR,
78                0.00769901118419740425 * .dAYS_PER_YEAR,
79                -0.0000690460016972063023 * .dAYS_PER_YEAR),
80                0.000954791938424326609 * .sOLAR_MASS),
81
82            'saturn': Body(Triple(8.34336671824457987,
83                4.12479856412430479,
84                -0.403523417114321381),
85                Triple(-0.00276742510726862411 * .dAYS_PER_YEAR,
86                0.00499852801234917238 * .dAYS_PER_YEAR,
87                0.0000230417297573763929 * .dAYS_PER_YEAR),
88                0.000285885980666130812 * .sOLAR_MASS),
89
90            'uranus': Body(Triple(12.8943695621391310,
91                -15.1111514016986312,
92                -0.223307578892655734),
93                Triple(0.00296460137564761618* .dAYS_PER_YEAR,
94                0.00237847173959480950* .dAYS_PER_YEAR,
95                -0.0000296589568540237556* .dAYS_PER_YEAR),
96                0.0000436624404335156298* .sOLAR_MASS),
97
98            'neptune': Body(Triple(15.3796971148509165,
99                -25.9193146099879641,
100                0.179258772950371181),
101                Triple(0.00268067772490389322* .dAYS_PER_YEAR,
102                0.00162824170038242295* .dAYS_PER_YEAR,
103                -0.0000951592254519715870* .dAYS_PER_YEAR),
104                0.0000515138902046611451* .sOLAR_MASS)
105        }
106        .sYSTEM = List<of Body>()
107        .sYSTEM.add(bodies['sun'])
108        .sYSTEM.add(bodies['jupiter'])
109        .sYSTEM.add(bodies['saturn'])
110        .sYSTEM.add(bodies['uranus'])
111        .sYSTEM.add(bodies['neptune'])
112        .pAIRS = .combinations(.sYSTEM)
113    var sYSTEM as List<of Body>
114    var sOLAR_MASS as float = 4 * 3.14159265358979323 *  3.14159265358979323
115    var dAYS_PER_YEAR as float = 365.24
116
117    var pAIRS as List<of BodyPair>
118
119
120    def advance(dt as float, n as int)
121        bodies=.sYSTEM
122        pairs=.pAIRS
123        b1 as Body = bodies[0]
124        b2 as Body = bodies[0]
125        v1 as Triple = b1.velocity
126        v2 as Triple = b2.velocity
127        dx as float
128        dy as float
129        dz as float
130        mag as float
131
132        for i in n
133            for p as BodyPair in pairs
134                b1 = p.body1
135                b2 = p.body2
136                v1, v2 =b1.velocity, b2.velocity
137                dx = b1.coord.x - b2.coord.x
138                dy = b1.coord.y - b2.coord.y
139                dz = b1.coord.z - b2.coord.z
140                mag = dt * (Math.pow(dx * dx + dy * dy + dz * dz, -1.5f) )
141                b1m as float= b1.mass * mag
142                b2m as float = b2.mass * mag
143                v1.x = v1.x - dx * b2m
144                v1.y = v1.y - dy * b2m
145                v1.z = v1.z - dz * b2m
146                v2.x = v2.x + dx * b1m
147                v2.y = v2.y + dy * b1m
148                v2.z = v2.z + dz * b1m
149            for b as Body in bodies
150                b.updateCoordinates(dt)
151
152
153    def report_energy
154        bodies=.sYSTEM
155        pairs=.pAIRS
156        #print "Bodies Count:[bodies.count]\nPairs Count:[pairs.count]"
157        e as float=0.0
158        for p as BodyPair in pairs
159            b1 as Body = p.body1
160            b2 as Body = p.body2
161            m = b1.mass * b2.mass
162            #print m
163            dx = b1.coord.x - b2.coord.x
164            dy = b1.coord.y - b2.coord.y
165            dz = b1.coord.z - b2.coord.z
166            sqrs = dx * dx + dy * dy + dz * dz
167            e -= m / Math.sqrt(sqrs )
168        for b as Body in bodies
169            e += b.mass * b.velocity.squared *0.5
170        print e
171
172    def offset_momentum(ref1 as Body)
173        bodies=.sYSTEM
174        px as float=0.0 
175        py as float=0.0
176        pz as float=0.0
177
178        for b as Body in bodies
179            m as float = b.mass
180            px = px- b.velocity.x * m
181            py = py-b.velocity.y * m
182            pz = pz-b.velocity.z * m
183        v, m = ref1.velocity, 1/ ref1.mass
184        v.x = px * m
185        v.y = py * m
186        v.z = pz * m
187        print v
188
189    def main
190        sw = System.Diagnostics.Stopwatch()
191        sw.start
192        .report_energy
193        .offset_momentum( .sYSTEM[0]) #sun
194        .report_energy
195        .advance(0.01, 50000)
196        .report_energy
197        sw.stop
198        print 'duration: [sw.elapsed] ms '
199