Created
October 25, 2018 13:18
-
-
Save lolgab/903a1492d42c274087472a36fd0051a6 to your computer and use it in GitHub Desktop.
Test changing for loops with while loops.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scalanative.native._ | |
import stdlib.malloc | |
object implicits { | |
type MVect3 = CStruct3[Double, Double, Double] | |
type MutableBody = CStruct3[MVect3, MVect3, Double] | |
implicit class MVect3Ops(val ptr: Ptr[MVect3]) extends AnyVal { | |
def x: Double = !ptr._1 | |
def y: Double = !ptr._2 | |
def z: Double = !ptr._3 | |
def x_=(v: Double): Unit = !ptr ._1 = v | |
def y_=(v: Double): Unit = !ptr ._2 = v | |
def z_=(v: Double): Unit = !ptr ._3 = v | |
def zero(): Unit = { | |
x = 0.0 | |
y = 0.0 | |
z = 0.0 | |
} | |
} | |
implicit class MutableBodyOps(val ptr: Ptr[MutableBody]) extends AnyVal { | |
def p: Ptr[MVect3] = ptr._1 | |
def v: Ptr[MVect3] = ptr._2 | |
def mass: Double = !ptr._3 | |
def mass_=(v: Double): Unit = !ptr._3 = v | |
} | |
} | |
class NBodyMutableClass(val numBodies: Int, val dt: Double) { | |
import implicits._ | |
private val bodies = malloc(numBodies * sizeof[MutableBody]).cast[Ptr[MutableBody]] | |
for(i <- 0 until numBodies) (bodies + i).mass = 1e-10 | |
private val accel = malloc(numBodies * sizeof[MVect3]).cast[Ptr[MVect3]] | |
initBodies() | |
def initBodies(): Unit = { | |
bodies.mass = 1.0 | |
for(i <- 1 until numBodies) { | |
(bodies + i).p.x = i | |
(bodies + i).v.y = math.sqrt(1.0/i) | |
} | |
} | |
def forSim(steps: Int): Unit = { | |
var s = 1 | |
while(s <= steps) { | |
var i = 0 | |
while(i < numBodies) { | |
(accel + i).zero() | |
i+=1 | |
} | |
i = 0 | |
while(i < numBodies) { | |
val pi = bodies + i | |
val acceli = accel + i | |
for (j <- i+1 until numBodies) { | |
val pj = bodies + j | |
val dx = pi.p.x-pj.p.x | |
val dy = pi.p.y-pj.p.y | |
val dz = pi.p.z-pj.p.z | |
val dist = math.sqrt(dx*dx+dy*dy+dz*dz) | |
val magi = pj.mass/(dist*dist*dist) | |
val magj = pi.mass/(dist*dist*dist) | |
acceli.x -= magi*dx | |
acceli.y -= magi*dy | |
acceli.z -= magi*dz | |
val accelj = (accel + j) | |
accelj.x += magj*dx | |
accelj.y += magj*dy | |
accelj.z += magj*dz | |
} | |
i+=1 | |
} | |
i = 0 | |
while(i < numBodies) { | |
val p = bodies + i | |
val acceli = (accel + i) | |
p.v.x += acceli.x*dt | |
p.v.y += acceli.y*dt | |
p.v.z += acceli.z*dt | |
p.p.x += p.v.x*dt | |
p.p.y += p.v.y*dt | |
p.p.z += p.v.z*dt | |
i+=1 | |
} | |
s+=1 | |
} | |
} | |
} | |
object MainTiming extends App { | |
val numBodies = 1000 | |
val dt = 0.01 | |
val mutSim = new NBodyMutableClass(numBodies, dt) | |
println("Mutable Class:") | |
val timeRuns = 20 | |
val times = new Array[Double](timeRuns) | |
var time = 0 | |
while(time < timeRuns) { | |
val start = System.nanoTime() | |
mutSim.forSim(100) | |
times(time) = (System.nanoTime()-start)*1e-9 | |
time += 1 | |
} | |
val mean = times.sum/times.length | |
val rms = math.sqrt(times.map(x => (x-mean)*(x-mean)).sum/times.length) | |
println(s"mean = $mean, rms = $rms") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment