1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| def symmetricEigs( mul: BDV[Double] => BDV[Double], n: Int, k: Int, tol: Double, maxIterations: Int): (BDV[Double], BDM[Double]) = { val arpack = ARPACK.getInstance() val tolW = new doubleW(tol) val nev = new intW(k) val ncv = math.min(2 * k, n) val bmat = "I" val which = "LM" var iparam = new Array[Int](11) iparam(0) = 1 iparam(2) = maxIterations iparam(6) = 1
var ido = new intW(0) var info = new intW(0) var resid = new Array[Double](n) var v = new Array[Double](n * ncv) var workd = new Array[Double](n * 3) var workl = new Array[Double](ncv * (ncv + 8)) var ipntr = new Array[Int](11)
arpack.dsaupd(ido, bmat, n, which, nev.`val`, tolW, resid, ncv, v, n, iparam, ipntr, workd, workl, workl.length, info) val w = BDV(workd) while (ido.`val` != 99) { if (ido.`val` != -1 && ido.`val` != 1) { throw new IllegalStateException("ARPACK returns ido = " + ido.`val` + " This flag is not compatible with Mode 1: A*x = lambda*x, A symmetric.") } val inputOffset = ipntr(0) - 1 val outputOffset = ipntr(1) - 1 val x = w.slice(inputOffset, inputOffset + n) val y = w.slice(outputOffset, outputOffset + n) y := mul(x) arpack.dsaupd(ido, bmat, n, which, nev.`val`, tolW, resid, ncv, v, n, iparam, ipntr, workd, workl, workl.length, info) }
val d = new Array[Double](nev.`val`) val select = new Array[Boolean](ncv) val z = java.util.Arrays.copyOfRange(v, 0, nev.`val` * n)
arpack.dseupd(true, "A", select, d, z, n, 0.0, bmat, n, which, nev, tol, resid, ncv, v, n, iparam, ipntr, workd, workl, workl.length, info)
val computed = iparam(4)
val eigenPairs = java.util.Arrays.copyOfRange(d, 0, computed).zipWithIndex.map { r => (r._1, java.util.Arrays.copyOfRange(z, r._2 * n, r._2 * n + n)) }
val sortedEigenPairs = eigenPairs.sortBy(- _._1)
val sortedU = BDM.zeros[Double](n, computed) sortedEigenPairs.zipWithIndex.foreach { r => val b = r._2 * n var i = 0 while (i < n) { sortedU.data(b + i) = r._1._2(i) i += 1 } } (BDV[Double](sortedEigenPairs.map(_._1)), sortedU) }
|