about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--generate.go210
1 files changed, 115 insertions, 95 deletions
diff --git a/generate.go b/generate.go
index 0059ca3..29f696c 100644
--- a/generate.go
+++ b/generate.go
@@ -1,18 +1,22 @@
 package main
 
 import (
+	"flag"
 	"fmt"
 	"gopkg.in/cheggaaa/pb.v1"
 	"math"
 	"math/rand"
 	"os"
+	"runtime"
+	"time"
+	//"os"
 )
 
 const (
-	sigma = 200.0
-	f_0   = 0.1
-	G     = 4.302e-3
-	R_s   = 1e4
+	sigma float64 = 200
+	f0    float64 = 0.1
+	G     float64 = 4.302e-3
+	rS    float64 = 1e4
 )
 
 type star struct {
@@ -22,136 +26,152 @@ type star struct {
 }
 
 func rho(x, y, z float64) float64 {
-	var r float64 = math.Sqrt((x * x) + (y * y) + (z * z))
-	var a float64 = (1) / (math.Sqrt(2*math.Pi) * sigma)
-	var b float64 = math.Exp(-(phi(r) / float64(sigma*sigma)))
-	//aphi := phi(r)
-	//asigma := float64(sigma * sigma)
-	//fmt.Println(aphi, asigma, math.Exp( - (aphi / asigma)))
+	r := math.Sqrt(math.Pow(x, 2) + math.Pow(y, 2) + math.Pow(z, 2))
+	a := (1) / (math.Sqrt(2*math.Pi) * sigma)
+	b := math.Exp(-phi(r) / math.Pow(sigma, 2))
 	return a * b
 }
 
 func phi(x float64) float64 {
 	if x == 0 {
-		return (-4 * math.Pi * f_0 * G * (R_s * R_s))
-	} else {
-		var a float64 = -(4 * math.Pi * G * f_0 * (R_s * R_s * R_s) / x)
-		var b float64 = math.Log(1.0 + (x / R_s))
-		return (a * b)
+		return -4 * math.Pi * f0 * G * math.Pow(rS, 2)
 	}
+	a := -(4 * math.Pi * f0 * G * math.Pow(rS, 3)) / x
+	b := math.Log(1.0 + (x / rS))
+	return a * b
 }
 
-func genStar(f *os.File) (bool, star) {
-	var length float64 = 1.5e7
+// generate the given amount of stars and pass them info the stars channel
+func genStars(threadNr int, amount int, starChannel chan star, galaxyRange float64) {
+
+	// Define variables
+	var length float64 = galaxyRange
 
+	// define the range of the galaxy
 	var rangeMin float64 = -length
 	var rangeMax float64 = length
-
 	var randMin float64 = rho(0, 0, 0)
 	var randMax float64 = rho(length, length, length)
 
-	//(max - min) * rand.Float64()) + min
-	var x float64 = ((rangeMax - rangeMin) * rand.Float64()) + rangeMin
-	var y float64 = ((rangeMax - rangeMin) * rand.Float64()) + rangeMin
-	var z float64 = ((rangeMax - rangeMin) * rand.Float64()) + rangeMin
+	var starCounter int = 0
 
-	var randVal float64 = (randMax-randMin)*rand.Float64() + randMin
+	randomSource := rand.New(rand.NewSource(time.Now().UnixNano()))
 
-	var rhoVal float64 = rho(x, y, z)
+	// iterate over the amount of stars
+	for starCounter < amount {
 
-	//fmt.Printf("x: %-20f y: %-20f z: %-20f randVal: %-20f rhoVal: %-20f\n", x, y, z, randVal, rhoVal)
+		// generate random coordinates
+		var x float64 = ((rangeMax - rangeMin) * randomSource.Float64()) + rangeMin
+		var y float64 = ((rangeMax - rangeMin) * randomSource.Float64()) + rangeMin
+		var z float64 = ((rangeMax - rangeMin) * randomSource.Float64()) + rangeMin
 
-	if randVal < rhoVal {
-		var starString string = fmt.Sprintf("%f, %f, %f\n", x, y, z)
-		_, err := f.WriteString(starString)
-		if err != nil {
-			panic(err)
-		}
-		f.Sync()
+		var randVal = ((randMax - randMin) * randomSource.Float64()) + randMin
 
-		//fmt.Printf("x: %-20f y: %-20f z: %-20f randVal: %-20f rhoVal: %-20f\n", x, y, z, randVal, rhoVal)
+		//fmt.Printf("%-25.15f %-25.15f %-25.15f %-25.15f %-25.15f\n", x, y, z, rho(x, y, z), randVal)
 
-		newStar := star{
-			x: x,
-			y: y,
-			z: z,
-		}
+		if randVal < rho(x, y, z) {
+			//fmt.Printf("[thread %2d] -> | %-20.10f | %-20.10f | %-20.10f | \n", threadNr, x, y, z)
 
-		// return that a star was generated
-		return true, newStar
-	}
+			var newStar star = star{x, y, z}
 
-	// return that no star was generated
-	return false, star{
-		x: 0,
-		y: 0,
-		z: 0,
+			// write the star to the file
+			starChannel <- newStar
+			starCounter += 1
+		}
 	}
 }
 
-func generateGoMethods(starCount int, f *os.File, channel chan star) {
-	var generatedStars int = 0
+func main() {
+	// define some variables
+	var amount int
+	var output string
+	hostname, _ := os.Hostname()
+	var pid int = os.Getpid()
+	var outputFileName string = fmt.Sprintf("data/%s_%d_%d.csv", hostname, pid, amount)
+	var threads int = runtime.NumCPU()
+	var galaxyRange float64
+
+	// Fill the variables using flags
+	flag.IntVar(&amount, "amount", 40, fmt.Sprintf("%-40s", "Amount of stars to be generated"))
+	flag.StringVar(&output, "output", "data/", fmt.Sprintf("%-40s", "Output File"))
+	flag.IntVar(&threads, "threads", runtime.NumCPU(), fmt.Sprintf("%-40s", "Amount of threads to be used"))
+	flag.Float64Var(&galaxyRange, "range", 1e6, fmt.Sprintf("%-40s", "Spacial size of the galaxy"))
+	flag.Parse()
+
+	// Calculate some new values
+	var threadAmount int = amount / threads
+	var remainingAmount int = amount - (threadAmount * threads)
+	var starSlice []star
+	var starChannel = make(chan star, 1024)
+
+	fmt.Printf("Starting %d threads. ", threads)
+	fmt.Printf("Each thread is generating %d stars\n", threadAmount)
+	if remainingAmount > 0 {
+		fmt.Printf("A seperate thread (-1) is generating the remaining %d stars\n\n", remainingAmount)
+	} else {
+		fmt.Printf("\n\n")
+	}
 
-	// for the amount of stars
-	for generatedStars < starCount {
+	startTime := time.Now()
 
-		// try to generate a new star
-		result, star := genStar(f)
-		if result == true {
-			generatedStars += 1
-			channel <- star
-		}
+	// Start all the goroutines
+	for i := 0; i < threads; i++ {
+		go genStars(i, threadAmount, starChannel, galaxyRange)
 	}
-}
 
-func main() {
-	// define some arguments
-	var stars int = 1e6
-	var threads int = 1
-	var threadStarCount int = stars / threads
+	// generate the missing stars
+	go genStars(-1, remainingAmount, starChannel, galaxyRange)
 
-	// create a channel with a buffer of 10
-	channel := make(chan star, 10)
+	progressBar := pb.New(amount)
+	progressBar.ShowFinalTime = true
+	progressBar.ShowSpeed = true
+	progressBar.Start()
 
-	// create a file that stores the data
-	hostname, _ := os.Hostname()
-	pid := os.Getpid()
-	f, err := os.Create(fmt.Sprintf("data/%s_%d.csv", hostname, pid))
+	// Bundle the stars
+	for j := 0; j < amount; j++ {
+		newStar := <-starChannel
+		starSlice = append(starSlice, newStar)
+		progressBar.Increment()
+	}
+
+	progressBar.Finish()
+
+	// Write the stars to a file
+	file, err := os.Create(outputFileName)
 	if err != nil {
 		panic(err)
 	}
+	defer file.Close()
 
-	// use 8 threads
-	// each thread should generate stars / 8 stars
-	for i := 0; i < threads; i++ {
-		fmt.Printf("Creating a happy worker! He/She is trying to generate %d stars!", threadStarCount)
-		// generate a go-method creating threadStarCound stars
-		go generateGoMethods(threadStarCount, f, channel)
-		fmt.Printf(" He/She just started working!\n")
+	for _, starElement := range starSlice {
+		file.WriteString(fmt.Sprintf("%f,%f,%f\n", starElement.x, starElement.y, starElement.z))
 	}
 
-	// start the missing threads threads
-	var missingStars int = stars - (threadStarCount * threads)
-	fmt.Printf("A special worker was assigned to generate the last %d stars.\n", missingStars)
-	go generateGoMethods(missingStars, f, channel)
+	// Stop the timer and print some useful information
+	endTime := time.Now()
+	elapsedTime := endTime.Sub(startTime)
+	fmt.Printf("\nGenerated %d Stars in %v\n", amount, elapsedTime)
 
-	var starSlice []star
+}
 
-	// Initialize a new progress bar
-	bar := pb.New(stars).Prefix("Stars: ")
-	bar.Start()
+/*############################################################
 
-	// get the stars
-	for i := 0; i < stars; i++ {
-		var newStar = <-channel
-		bar.Increment()
-		starSlice = append(starSlice, newStar)
-	}
+Stats:
 
-	bar.Finish()
+size:	1e5
+amount:	1e6
+time:	14m21s
 
-	// print all elements in the starslice
-	for _, element := range starSlice {
-		fmt.Println(element)
-	}
-}
+size:	1e5
+amount 	1e4
+time:	953.53ms
+
+size: 	1e6
+amount: 1e4
+time:	1m46s
+
+size: 	1e7
+amount:	1e4
+time:	19m31s
+
+############################################################*/