Scala benchmark: step rotation by multiplying
This makes the algorithm more consistent with the Rust benchmark.
This commit is contained in:
parent
3665351e12
commit
27ada6566b
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user