Task: N-body problem




Go: package main

import (
    "fmt"
    "math"
    "os"
)

type vector struct{ x, y, z float64 }

func (v vector) add(w vector) vector {
    return vector{v.x + w.x, v.y + w.y, v.z + w.z}
}

func (v vector) sub(w vector) vector {
    return vector{v.x - w.x, v.y - w.y, v.z - w.z}
}

func (v vector) scale(m float64) vector {
    return vector{v.x * m, v.y * m, v.z * m}
}

func (v vector) mod() float64 {
    return math.Sqrt(v.x*v.x + v.y*v.y + v.z*v.z)
}

var (
    bodies, timeSteps                    int
    masses                               []float64
    gc                                   float64
    positions, velocities, accelerations []vector
)

func initiateSystem(fileName string) error {
    file, err := os.Open(fileName)
    if err != nil {
        return err
    }
    defer file.Close()
    fmt.Fscanf(file, "%f%d%d", &gc, &bodies, &timeSteps)
    masses = make([]float64, bodies)
    positions = make([]vector, bodies)
    velocities = make([]vector, bodies)
    accelerations = make([]vector, bodies)
    for i := 0; i < bodies; i++ {
        fmt.Fscanf(file, "%f", &masses[i])
        fmt.Fscanf(file, "%f%f%f", &positions[i].x, &positions[i].y, &positions[i].z)
        fmt.Fscanf(file, "%f%f%f", &velocities[i].x, &velocities[i].y, &velocities[i].z)
    }
    return nil
}

func resolveCollisions() {
    for i := 0; i < bodies-1; i++ {
        for j := i + 1; j < bodies; j++ {
            if positions[i] == positions[j] {
                velocities[i], velocities[j] = velocities[j], velocities[i]
            }
        }
    }
}

func computeAccelerations() {
    for i := 0; i < bodies; i++ {
        accelerations[i] = vector{0, 0, 0}
        for j := 0; j < bodies; j++ {
            if i != j {
                temp := gc * masses[j] / math.Pow(positions[i].sub(positions[j]).mod(), 3)
                accelerations[i] = accelerations[i].add(positions[j].sub(positions[i]).scale(temp))
            }
        }
    }
}

func computeVelocities() {
    for i := 0; i < bodies; i++ {
        velocities[i] = velocities[i].add(accelerations[i])
    }
}

func computePositions() {
    for i := 0; i < bodies; i++ {
        positions[i] = positions[i].add(velocities[i].add(accelerations[i].scale(0.5)))
    }
}

func simulate() {
    computeAccelerations()
    computePositions()
    computeVelocities()
    resolveCollisions()
}

func printResults() {
    f := "Body %d : % 8.6f  % 8.6f  % 8.6f | % 8.6f  % 8.6f  % 8.6f\n"
    for i := 0; i < bodies; i++ {
        fmt.Printf(
            f, i+1,
            positions[i].x, positions[i].y, positions[i].z,
            velocities[i].x, velocities[i].y, velocities[i].z,
        )
    }
}

func main() {
    if len(os.Args) != 2 {
        fmt.Printf("Usage : %s <file name containing system configuration data>\n", os.Args[0])
    } else {
        err := initiateSystem(os.Args[1])
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Print("Body   :      x          y          z    |")
        fmt.Println("     vx         vy         vz")
        for i := 0; i < timeSteps; i++ {
            fmt.Printf("\nCycle %d\n", i+1)
            simulate()
            printResults()
        }
    }
}




Python: import math

class Vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y, self.z + other.z)

    def __sub__(self, other):
        return Vector(self.x - other.x, self.y - other.y, self.z - other.z)

    def __mul__(self, other):
        return Vector(self.x * other, self.y * other, self.z * other)

    def __div__(self, other):
        return Vector(self.x / other, self.y / other, self.z / other)

    def __eq__(self, other):
        if isinstance(other, Vector):
            return self.x == other.x and self.y == other.y and self.z == other.z
        return False

    def __ne__(self, other):
        return not self.__eq__(other)

    def __str__(self):
        return '({x}, {y}, {z})'.format(x=self.x, y=self.y, z=self.z)

    def abs(self):
        return math.sqrt(self.x*self.x + self.y*self.y + self.z*self.z)

origin = Vector(0, 0, 0)

class NBody:
    def __init__(self, fileName):
        with open(fileName, "r") as fh:
            lines = fh.readlines()
            gbt = lines[0].split()
            self.gc = float(gbt[0])
            self.bodies = int(gbt[1])
            self.timeSteps = int(gbt[2])
            self.masses = [0.0 for i in range(self.bodies)]
            self.positions = [origin for i in range(self.bodies)]
            self.velocities = [origin for i in range(self.bodies)]
            self.accelerations = [origin for i in range(self.bodies)]
            for i in range(self.bodies):
                self.masses[i] = float(lines[i*3 + 1])
                self.positions[i] = self.__decompose(lines[i*3 + 2])
                self.velocities[i] = self.__decompose(lines[i*3 + 3])

            print "Contents of", fileName
            for line in lines:
                print line.rstrip()
            print
            print "Body   :      x          y          z    |",
            print "     vx         vy         vz"

    def __decompose(self, line):
        xyz = line.split()
        x = float(xyz[0])
        y = float(xyz[1])
        z = float(xyz[2])
        return Vector(x, y, z)

    def __computeAccelerations(self):
        for i in xrange(self.bodies):
            self.accelerations[i] = origin
            for j in xrange(self.bodies):
                if i != j:
                    temp = self.gc * self.masses[j] / math.pow((self.positions[i] - self.positions[j]).abs(), 3)
                    self.accelerations[i] += (self.positions[j] - self.positions[i]) * temp
        return None

    def __computePositions(self):
        for i in xrange(self.bodies):
            self.positions[i] += self.velocities[i] + self.accelerations[i] * 0.5
        return None

    def __computeVelocities(self):
        for i in xrange(self.bodies):
            self.velocities[i] += self.accelerations[i]
        return None

    def __resolveCollisions(self):
        for i in xrange(self.bodies):
            for j in xrange(self.bodies):
                if self.positions[i] == self.positions[j]:
                    (self.velocities[i], self.velocities[j]) = (self.velocities[j], self.velocities[i])
        return None

    def simulate(self):
        self.__computeAccelerations()
        self.__computePositions()
        self.__computeVelocities()
        self.__resolveCollisions()
        return None

    def printResults(self):
        fmt = "Body %d : % 8.6f  % 8.6f  % 8.6f | % 8.6f  % 8.6f  % 8.6f"
        for i in xrange(self.bodies):
            print fmt % (i+1, self.positions[i].x, self.positions[i].y, self.positions[i].z, self.velocities[i].x, self.velocities[i].y, self.velocities[i].z)
        return None

nb = NBody("nbody.txt")
for i in xrange(nb.timeSteps):
    print "\nCycle %d" % (i + 1)
    nb.simulate()
    nb.printResults()