Skip to content

Instantly share code, notes, and snippets.

@dacr
Last active April 2, 2023 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/79bfbdb6945613a4239606e444c3a55a to your computer and use it in GitHub Desktop.
Save dacr/79bfbdb6945613a4239606e444c3a55a to your computer and use it in GitHub Desktop.
the logistic map - bifurcation diagram / La suite logistique - diagramme de bifurcation / published by https://github.com/dacr/code-examples-manager #e294d28a-aa97-4a4a-9a97-3cef7d22fd65/86f53aeb447c7a600e80272ab7a21d76413b68de
// summary : the logistic map - bifurcation diagram / La suite logistique - diagramme de bifurcation
// keywords : math, logistic-map, fractal, chaos, breeze, bifurcation-diagram
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : e294d28a-aa97-4a4a-9a97-3cef7d22fd65
// created-on : 2021-02-26T15:34:32Z
// managed-by : https://github.com/dacr/code-examples-manager
// execution : scala ammonite script (http://ammonite.io/) - run as follow 'amm scriptname.sc'
// logistic map info -> https://en.wikipedia.org/wiki/Logistic_map
// veritasium video -> https://www.youtube.com/watch?v=ovJcsL7vyrk
import $ivy.`org.plotly-scala::plotly-render:0.8.1`
import plotly._ ,element._ ,layout._ ,Plotly._
import java.math.MathContext
val computeMathContext = new MathContext(10) // constraint the total number of digits
val valuesKeeperRoundContext = new MathContext(4) // constraint the total number of digits
def logMap(xn: BigDecimal, r: BigDecimal): BigDecimal = r * xn * (1 - xn)
def logMapAnalysis(givenR: Double, maxGenerations: Int, ignoreGenerationsBelow:Int, givenX0:Double = 0.5): Set[BigDecimal] = {
val r = BigDecimal(givenR, computeMathContext)
val x0 = BigDecimal(givenX0, computeMathContext)
def generations = {
LazyList
.from(1)
.scanLeft(Tuple2(x0, Set.empty[BigDecimal])) {
case ((xp, values), gen) if gen < ignoreGenerationsBelow => logMap(xp, r) -> values
case ((xp, values), _) =>
val xn = logMap(xp, r)
xn -> (values + xn.round(valuesKeeperRoundContext))
}
}
generations.drop(maxGenerations).head match {
case (xn, values) => values
}
}
// =================================================================================================
val points = {
LazyList
.iterate(1.5d)(_ + 0.001d)
.takeWhile(_ < 4.0d)
.flatMap(r => logMapAnalysis(r, 100, 50).map(value => r -> value.toDouble))
}
val (xs, ys) = points.unzip
println("Number of points generated : "+points.size)
// =================================================================================================
val plotlyData = Seq(
Scatter(xs, ys)
.withName("LogisticMap")
.withMode(ScatterMode(ScatterMode.Markers))
.withMarker(Marker().withSize(1))
)
val plotlyLayout = Layout().withTitle("LogisticMapTrend").withHeight(800).withWidth(1200)
plot("plot.html", plotlyData, plotlyLayout)
//scala.io.StdIn.readLine("Press enter to quit")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment