Skip to content

Instantly share code, notes, and snippets.

@elmariachi111
Last active July 28, 2017 09:09
Show Gist options
  • Save elmariachi111/205daab6d9f71537d8a36b13f3c7a5f5 to your computer and use it in GitHub Desktop.
Save elmariachi111/205daab6d9f71537d8a36b13f3c7a5f5 to your computer and use it in GitHub Desktop.
Feigenbaum's bifurcation diagram in Go
package main
import (
"image"
"os"
"image/png"
"image/color"
"image/draw"
"runtime"
)
func logistic(x float64, r float64, it int) float64 {
for i := 0; i < it; i++ {
x = r * x * (1 - x)
}
return x
}
func logr(im *image.RGBA, x float64, its int) {
var i,j int = 0,0
var X,Y float64= (float64)(im.Bounds().Max.X), (float64)(im.Bounds().Max.Y)
steps := 1.2 / X
for r := 2.8 ; r < 4.0 ; r += steps {
res := logistic(x, r, its)
i = (int)((X * (r-2.8)/1.2) )
j = (int)((Y - Y * res))
k := im.RGBAAt(i,j)
if (k.A == 255) {
if (k.R > 1) {
k.R = k.R - 1
k.G = k.G - 1
k.B = k.B - 1
}
} else {
k.R = 175
k.G = 175
k.B = 175
k.A = 255
}
im.Set(i, j, k)
}
}
func computeX(im *image.RGBA, stepSize float64, from float64, to float64, c chan bool) {
for its := 50 ; its < 150 ; its += 10 {
for x := from; x < to; x += stepSize {
logr(im, x, its)
}
}
c <- true
}
func main() {
im := image.NewRGBA(image.Rect(0,0,2550,1080))
gr := color.RGBA{220,220,220,255}
draw.Draw(im, im.Bounds(), &image.Uniform{gr}, image.ZP, draw.Src)
var numCPU = runtime.NumCPU()
stepSize := (1.0-0.01) / 2550.0
sliceSize := 1.0/(float64)(numCPU)
c := make(chan bool, numCPU)
for cpu := 0 ; cpu < numCPU; cpu++ {
from := (float64)(cpu) * sliceSize
to := (float64)(cpu+1) * sliceSize
go computeX(im, stepSize, from, to , c)
}
for cpu := 0; cpu < numCPU; cpu++ {
<-c // wait for one task to complete
}
imgFile, err := os.Create("feigenbaum.png")
if err != nil {
return
}
defer imgFile.Close()
png.Encode(imgFile, im)
}
@elmariachi111
Copy link
Author

elmariachi111 commented Jul 17, 2016

added "parallelism" through concurrency.
feigenbaum

there are fewer iterations involved at all (but I went up to 150 iterations of the rlogx fixpoint iteration) so the second image shows slightly more "precise" results and fewer "unprecise" results in the "wrong" areas leading to fewer dark shades.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment