Compare commits

...

2 Commits

Author SHA1 Message Date
Aaron Fenyes
144bfb8faf Scala benchmark: use fullLinkJS output
The JavaScript produced by `fullLinkJS` is about twice as fast as the
code produced by `fastLinkJS`.
2024-08-10 21:30:36 -07:00
Aaron Fenyes
27ada6566b Scala benchmark: step rotation by multiplying
This makes the algorithm more consistent with the Rust benchmark.
2024-08-10 19:11:55 -07:00
2 changed files with 32 additions and 22 deletions

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>The circular law</title> <title>The circular law</title>
<script type="text/javascript" src="./target/scala-3.4.2/circular-law-fastopt/main.js"></script> <script type="text/javascript" src="./target/scala-3.4.2/circular-law-opt/main.js"></script>
<link rel="stylesheet" href="main.css"/> <link rel="stylesheet" href="main.css"/>
</head> </head>
<body></body> <body></body>

View File

@ -2,6 +2,7 @@ import com.raquo.laminar.api.L.{*, given}
import narr.* import narr.*
import org.scalajs.dom import org.scalajs.dom
import org.scalajs.dom.document import org.scalajs.dom.document
import scala.collection.mutable.ArrayBuffer
import scala.math.{cos, sin} import scala.math.{cos, sin}
import slash.matrix.Matrix import slash.matrix.Matrix
import slash.matrix.decomposition.Eigen import slash.matrix.decomposition.Eigen
@ -38,36 +39,45 @@ object CircularLawApp:
) )
ctx.fill() ctx.fill()
def eigvalsRotated[N <: Int](A: Matrix[N, N], time: Double)(using ValueOf[N]): (NArray[Double], NArray[Double]) = def complexEigenvalues[N <: Int](mat: Matrix[N, N])(using ValueOf[N]): (NArray[Double], NArray[Double]) =
// create transformation val eigen = Eigen(mat)
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.realEigenvalues.asInstanceOf[NArray[Double]],
eigen.imaginaryEigenvalues.asInstanceOf[NArray[Double]] eigen.imaginaryEigenvalues.asInstanceOf[NArray[Double]]
) )
def randEigvalSeries[N <: Int]()(using ValueOf[N]): (List[(NArray[Double], NArray[Double])], String) = def randEigvalSeries[N <: Int]()(using ValueOf[N]): (ArrayBuffer[(NArray[Double], NArray[Double])], String) =
val timeRes = 100 // start timing
val dim: Int = valueOf[N]
val startTime = System.currentTimeMillis() val startTime = System.currentTimeMillis()
val A = new Matrix[N, N](
// initialize the random matrix step
val dim: Int = valueOf[N]
var randMat = new Matrix[N, N](
NArray.tabulate(dim*dim)(k => (math.E*k*k) % 2 - 1) NArray.tabulate(dim*dim)(k => (math.E*k*k) % 2 - 1)
).times(math.sqrt(3d / dim)) ).times(math.sqrt(3d / dim))
val series = List.tabulate(timeRes)(t => eigvalsRotated(A, t.toDouble / timeRes))
// initialize the rotation step
val timeRes = 100
val maxFreq = 4
val rotStep = Matrix.identity[N, N]
for n <- 0 to dim by 2 do
val ang = math.Pi * (n % maxFreq) / timeRes
val cos_ang = cos(ang)
val sin_ang = sin(ang)
rotStep(n, n) = cos_ang
rotStep(n+1, n) = sin_ang
rotStep(n, n+1) = -sin_ang
rotStep(n+1, n+1) = cos_ang
// find the eigenvalues
val eigvalSeries = ArrayBuffer(complexEigenvalues(randMat))
for _ <- 1 to timeRes-1 do
randMat = rotStep * randMat
eigvalSeries += complexEigenvalues(randMat)
// finish timing
val runTime = System.currentTimeMillis() - startTime val runTime = System.currentTimeMillis() - startTime
(series, runTime.toString() + " ms") (eigvalSeries, runTime.toString() + " ms")
def main(args: Array[String]): Unit = def main(args: Array[String]): Unit =
ctx.fillStyle = "white" ctx.fillStyle = "white"