Scala trial: write benchmark
This commit is contained in:
parent
0bd025dd14
commit
6b0fad89dc
2
lang-trials/scala-benchmark/.gitignore
vendored
Normal file
2
lang-trials/scala-benchmark/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target
|
||||
sbt.json
|
9
lang-trials/scala-benchmark/build.sbt
Normal file
9
lang-trials/scala-benchmark/build.sbt
Normal file
@ -0,0 +1,9 @@
|
||||
enablePlugins(ScalaJSPlugin)
|
||||
|
||||
name := "Circular Law"
|
||||
scalaVersion := "3.4.2"
|
||||
scalaJSUseMainModuleInitializer := true
|
||||
|
||||
libraryDependencies += "com.raquo" %%% "laminar" % "17.0.0"
|
||||
libraryDependencies += "ai.dragonfly" %%% "slash" % "0.3.1"
|
||||
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.8.0"
|
10
lang-trials/scala-benchmark/index.html
Normal file
10
lang-trials/scala-benchmark/index.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>The circular law</title>
|
||||
<script type="text/javascript" src="./target/scala-3.4.2/circular-law-fastopt/main.js"></script>
|
||||
<link rel="stylesheet" href="main.css"/>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
22
lang-trials/scala-benchmark/main.css
Normal file
22
lang-trials/scala-benchmark/main.css
Normal file
@ -0,0 +1,22 @@
|
||||
body {
|
||||
margin-left: 20px;
|
||||
margin-top: 20px;
|
||||
color: #fcfcfc;
|
||||
background-color: #202020;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
canvas {
|
||||
float: left;
|
||||
background-color: #020202;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-top: 5px;
|
||||
}
|
1
lang-trials/scala-benchmark/project/build.properties
Normal file
1
lang-trials/scala-benchmark/project/build.properties
Normal file
@ -0,0 +1 @@
|
||||
sbt.version=1.10.1
|
1
lang-trials/scala-benchmark/project/plugins.sbt
Normal file
1
lang-trials/scala-benchmark/project/plugins.sbt
Normal file
@ -0,0 +1 @@
|
||||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
|
@ -0,0 +1,91 @@
|
||||
import com.raquo.laminar.api.L.{*, given}
|
||||
import narr.*
|
||||
import org.scalajs.dom
|
||||
import org.scalajs.dom.document
|
||||
import scala.math.{cos, sin}
|
||||
import slash.matrix.Matrix
|
||||
import slash.matrix.decomposition.Eigen
|
||||
|
||||
object CircularLawApp:
|
||||
val canvas = canvasTag(widthAttr := 600, heightAttr := 600)
|
||||
val ctx = canvas.ref.getContext("2d").asInstanceOf[dom.CanvasRenderingContext2D]
|
||||
|
||||
val (eigvalSeries, runTimeReport) = randomEigvalSeries[60]()
|
||||
val timeVar = Var("0")
|
||||
|
||||
def draw(timeStr: String): Unit =
|
||||
// center and normalize the coordinate system
|
||||
val width = canvas.ref.width
|
||||
val height = canvas.ref.height
|
||||
ctx.setTransform(1d, 0d, 0d, -1d, 0.5*width, 0.5*height)
|
||||
|
||||
// clear the previous frame
|
||||
ctx.clearRect(-0.5*width, -0.5*width, width, height)
|
||||
|
||||
// find the resolution
|
||||
val rDisp: Double = 1.5
|
||||
val res = width / (2*rDisp)
|
||||
|
||||
// draw the eigenvalues
|
||||
val eigvals = eigvalSeries(timeStr.toInt)
|
||||
for n <- 0 to eigvals(0).length-1 do
|
||||
ctx.beginPath()
|
||||
ctx.arc(
|
||||
res * eigvals(0)(n),
|
||||
res * eigvals(1)(n),
|
||||
3d,
|
||||
0d, 2*math.Pi
|
||||
)
|
||||
ctx.fill()
|
||||
|
||||
def eigvalsRotated[N <: Int](A: Matrix[N, N], time: Double)(using ValueOf[N]): (NArray[Double], NArray[Double]) =
|
||||
// create transformation
|
||||
val maxFreq = 4
|
||||
val T = Matrix.identity[N, N]
|
||||
val dim: Int = valueOf[N]
|
||||
for n <- 0 to dim by 2 do
|
||||
val a = cos(math.Pi * time * (n % maxFreq))
|
||||
val b = sin(math.Pi * time * (n % maxFreq))
|
||||
T(n, n) = a
|
||||
T(n+1, n) = b
|
||||
T(n, n+1) = -b
|
||||
T(n+1, n+1) = a
|
||||
|
||||
// find eigenvalues
|
||||
val eigen = Eigen(T*A)
|
||||
(
|
||||
eigen.realEigenvalues.asInstanceOf[NArray[Double]],
|
||||
eigen.imaginaryEigenvalues.asInstanceOf[NArray[Double]]
|
||||
)
|
||||
|
||||
def randomEigvalSeries[N <: Int]()(using ValueOf[N]): (List[(NArray[Double], NArray[Double])], String) =
|
||||
val timeRes = 100
|
||||
val dim: Int = valueOf[N]
|
||||
val startTime = System.currentTimeMillis()
|
||||
val A = new Matrix[N, N](
|
||||
NArray.tabulate(dim*dim)(k => (math.E*k*k) % 2 - 1)
|
||||
).times(math.sqrt(3d / dim))
|
||||
val series = List.tabulate(timeRes)(t => eigvalsRotated(A, t.toDouble / timeRes))
|
||||
val endTime = System.currentTimeMillis()
|
||||
val runTime = endTime - startTime
|
||||
(series, runTime.toString() + " ms")
|
||||
|
||||
def main(args: Array[String]): Unit =
|
||||
ctx.fillStyle = "white"
|
||||
|
||||
lazy val app = div(
|
||||
idAttr := "app",
|
||||
div(runTimeReport),
|
||||
canvas,
|
||||
input(
|
||||
typ := "range",
|
||||
minAttr := "0",
|
||||
maxAttr := (eigvalSeries.length-1).toString,
|
||||
controlled(
|
||||
value <-- timeVar.signal,
|
||||
onInput.mapToValue --> timeVar.writer
|
||||
),
|
||||
timeVar.signal --> draw
|
||||
)
|
||||
)
|
||||
renderOnDomContentLoaded(document.body, app)
|
Loading…
Reference in New Issue
Block a user