progs/mandelbrot.sc
changeset 491 e2ffe8642f55
parent 490 4778fefecd0c
child 493 244df77507c2
equal deleted inserted replaced
490:4778fefecd0c 491:e2ffe8642f55
     1 // Mandelbrot pictures
     1 // Mandelbrot pictures
     2 //=====================
     2 //=====================
     3 //
     3 //
     4 //   see https://en.wikipedia.org/wiki/Mandelbrot_set
     4 //   see https://en.wikipedia.org/wiki/Mandelbrot_set
     5 //
     5 //
     6 // needs to be called with
     6 // You can run on the file one the commandline with
     7 //
     7 //
     8 //   scala-cli --extra-jars scala-parallel-collections_3-1.0.4.jar
     8 //   scala-cli mandelbrot.sc
     9 //
       
    10 // the jar-file is uploaded to KEATS
       
    11 //
     9 //
    12 //
    10 //
    13 // !! UPDATE ON TIMING: On my faster Mac-M1 machine 
    11 //
    14 // !! the times for the first example are ca. 4 secs for 
    12 // !! UPDATE ON TIMING: On my faster Mac-M1 machine
    15 // !! the sequential version and around 0.7 secs for the 
    13 // !! the times for the first example are ca. 4 secs for
       
    14 // !! the sequential version and around 0.7 secs for the
    16 // !! par-version.
    15 // !! par-version.
    17 
    16 
       
    17 // for parallel collections
       
    18 //> using dep org.scala-lang.modules::scala-parallel-collections:1.0.4
       
    19 import scala.language.implicitConversions
       
    20 import scala.collection.parallel.CollectionConverters.*
    18 
    21 
       
    22 // for graphics
    19 import javax.swing.{JFrame, JPanel, WindowConstants}
    23 import javax.swing.{JFrame, JPanel, WindowConstants}
    20 import java.awt.{Color, Dimension, Graphics, Graphics2D}
    24 import java.awt.{Color, Dimension, Graphics, Graphics2D}
    21 import java.awt.image.BufferedImage
    25 import java.awt.image.BufferedImage
    22 
    26 
    23 import scala.language.implicitConversions
    27 
    24 import scala.collection.parallel.CollectionConverters.*
    28 
    25 
    29 
    26 // complex numbers
    30 // complex numbers
    27 // represents the complex number re + im * i
    31 //   represents the complex number re + im * i
    28 case class Complex(val re: Double, val im: Double) {
    32 case class Complex(val re: Double, val im: Double) {
    29   
    33 
    30   def +(that: Complex) = Complex(this.re + that.re, this.im + that.im)
    34   def +(that: Complex) = Complex(this.re + that.re, this.im + that.im)
    31   def -(that: Complex) = Complex(this.re - that.re, this.im - that.im)
    35   def -(that: Complex) = Complex(this.re - that.re, this.im - that.im)
    32   def *(that: Complex) = Complex(this.re * that.re - this.im * that.im,
    36   def *(that: Complex) = Complex(this.re * that.re - this.im * that.im,
    33                                  this.re * that.im + that.re * this.im)
    37                                  this.re * that.im + that.re * this.im)
    34   def *(that: Double) = Complex(this.re * that, this.im * that)
    38   def *(that: Double) = Complex(this.re * that, this.im * that)
    39 object i extends Complex(0, 1)
    43 object i extends Complex(0, 1)
    40 
    44 
    41 // implicit conversion from Doubles to Complex
    45 // implicit conversion from Doubles to Complex
    42 given Conversion[Double, Complex] = Complex(_, 0)
    46 given Conversion[Double, Complex] = Complex(_, 0)
    43 
    47 
    44 // some customn colours for the "sliding effect"
    48 // some customn colours for the "sliding effect" outside
       
    49 // the mandelbrot set
    45 val colours = List(
    50 val colours = List(
    46   Color(66, 30, 15),    Color(25, 7, 26),
    51   Color(66, 30, 15),    Color(25, 7, 26),
    47   Color(9, 1, 47),      Color(4, 4, 73),
    52   Color(9, 1, 47),      Color(4, 4, 73),
    48   Color(0, 7, 100),     Color(12, 44, 138),
    53   Color(0, 7, 100),     Color(12, 44, 138),
    49   Color(24, 82, 177),   Color(57, 125, 209),
    54   Color(24, 82, 177),   Color(57, 125, 209),
    69   }
    74   }
    70 }
    75 }
    71 
    76 
    72 // initialising the viewer panel
    77 // initialising the viewer panel
    73 def openViewer(width: Int, height: Int) : Viewer = {
    78 def openViewer(width: Int, height: Int) : Viewer = {
       
    79   val viewer = Viewer(width, height)
    74   val frame = JFrame("XYPlane")
    80   val frame = JFrame("XYPlane")
    75   val viewer = Viewer(width, height)
       
    76   frame.add(viewer)
    81   frame.add(viewer)
    77   frame.pack()
    82   frame.pack()
    78   frame.setVisible(true)
    83   frame.setVisible(true)
    79   frame.setResizable(false)
    84   frame.setResizable(false)
    80   frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
    85   frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
   114   for (y <- (0 until H).par) {
   119   for (y <- (0 until H).par) {
   115     for (x <- (0 until W).par) {
   120     for (x <- (0 until W).par) {
   116 
   121 
   117      val c = start + x * d_x + y * d_y * i
   122      val c = start + x * d_x + y * d_y * i
   118      val iters = iterations(c, max)
   123      val iters = iterations(c, max)
   119      val colour = 
   124      val colour =
   120         if (iters == max) black
   125         if (iters == max) black
   121         else colours(iters % 16)
   126         else colours(iters % 16)
   122 
   127 
   123      pixel(x, y, colour)
   128      pixel(x, y, colour)
   124     }
   129     }
   125     viewer.updateUI()
   130     viewer.updateUI()
   126   }
   131   }
   127 }
   132 }
       
   133 
       
   134 
   128 
   135 
   129 
   136 
   130 // Examples
   137 // Examples
   131 //==========
   138 //==========
   132 
   139 
   156 val exc1 = 0.435396403 + 0.367981352 * i
   163 val exc1 = 0.435396403 + 0.367981352 * i
   157 val exc2 = 0.451687191 + 0.380210061 * i
   164 val exc2 = 0.451687191 + 0.380210061 * i
   158 
   165 
   159 //time_needed(mandelbrot(exc1, exc2, 1000))
   166 //time_needed(mandelbrot(exc1, exc2, 1000))
   160 
   167 
   161 
       
   162 
       
   163 // some more computations with example 3
   168 // some more computations with example 3
   164 
   169 
   165 val delta = (exc2 - exc1) * 0.0333
   170 val delta = (exc2 - exc1) * 0.01
   166 
   171 
   167 println(s"${time_needed(
   172 println(s"${time_needed(
   168   for (n <- (0 to 25))
   173   for (n <- (0 to 25))
   169      mandelbrot(exc1 + delta * n,
   174      mandelbrot(exc1 + delta * n,
   170                 exc2 - delta * n, 1000))} secs")
   175                 exc2 - delta * n, 1000))} secs")