From dccfa7f8ffeca5e59f31c5f57aacd12c835f7b49 Mon Sep 17 00:00:00 2001 From: hanemile Date: Thu, 1 Nov 2018 20:31:08 +0100 Subject: Complete update --- generate.go | 210 +++++++++++++++++++++++++++++++++--------------------------- 1 file 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 + +############################################################*/ -- cgit 1.4.1