func TestTriRedUpper(t *testing.T) { N := 843 nb := 48 conf := gomas.NewConf() conf.LB = 0 A := cmat.NewMatrix(N, N) tau := cmat.NewMatrix(N, 1) src := cmat.NewFloatNormSource() A.SetFrom(src, cmat.UPPER) A1 := cmat.NewCopy(A) tau1 := cmat.NewCopy(tau) _ = A1 W := lapackd.Workspace(N) W1 := lapackd.Workspace(N * nb) lapackd.TRDReduce(A, tau, W, gomas.UPPER, conf) conf.LB = nb lapackd.TRDReduce(A1, tau1, W1, gomas.UPPER, conf) blasd.Plus(A, A1, -1.0, 1.0, gomas.NONE) nrm := lapackd.NormP(A, lapackd.NORM_ONE) t.Logf("N=%d, ||unblk.Trired(A) - blk.Trired(A)||_1: %e\n", N, nrm) blasd.Axpy(tau, tau1, -1.0) nrm = blasd.Nrm2(tau) t.Logf(" ||unblk.Trired(tau) - blk.Trired(tau)||_1: %e\n", nrm) }
// Compute eigenvector corresponding precomputed deltas func trdsecEigenVecDelta(qi, delta, z *cmat.FloatMatrix) { var dk, zk float64 for k := 0; k < delta.Len(); k++ { zk = z.GetAt(k) dk = delta.GetAt(k) qi.SetAt(k, zk/dk) } s := blasd.Nrm2(qi) blasd.InvScale(qi, s) }
// test: unblk.QLFactor == blk.QLFactor func TestQLFactor(t *testing.T) { var t0 cmat.FloatMatrix M := 911 N := 835 nb := 32 conf := gomas.NewConf() A := cmat.NewMatrix(M, N) src := cmat.NewFloatNormSource() A.SetFrom(src) tau := cmat.NewMatrix(M, 1) W := cmat.NewMatrix(M+N, 1) A1 := cmat.NewCopy(A) tau1 := cmat.NewCopy(tau) conf.LB = 0 lapackd.QLFactor(A, tau, W, conf) conf.LB = nb W1 := lapackd.Workspace(lapackd.QLFactorWork(A1, conf)) lapackd.QLFactor(A1, tau1, W1, conf) if N < 10 { t.Logf("unblkQL(A):\n%v\n", A) t0.SetBuf(1, tau.Len(), 1, tau.Data()) t.Logf("unblkQL.tau:\n%v\n", &t0) t.Logf("blkQL(A):\n%v\n", A1) t0.SetBuf(1, tau1.Len(), 1, tau1.Data()) t.Logf("blkQL.tau:\n%v\n", &t0) } blasd.Plus(A1, A, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(A1, lapackd.NORM_ONE) t.Logf("M=%d, N=%d ||blkQL(A) - unblkQL(A)||_1: %e\n", M, N, nrm) blasd.Axpy(tau1, tau, -1.0) nrm = blasd.Nrm2(tau1) t.Logf(" ||blkQL.tau - unblkQL.tau||_1: %e\n", nrm) }
/* * Compute matrix and vector norms. * * Arguments * X A real valued matrix or vector * * norm Norm to compute * NORM_ONE, NORM_TWO, NORM_INF * * Note: matrix NORM_TWO not yet implemented. */ func NormP(X *cmat.FloatMatrix, norm Norms) float64 { if X.IsVector() { switch norm { case NORM_ONE: return blasd.ASum(X) case NORM_TWO: return blasd.Nrm2(X) case NORM_INF: return blasd.Amax(X) } return 0.0 } switch norm { case NORM_ONE: return mNorm1(X) case NORM_TWO: return 0.0 case NORM_INF: return mNormInf(X) } return 0.0 }
func trdsecEigenBuildInplace(Q, z *cmat.FloatMatrix) { var QTL, QBR, Q00, q11, q12, q21, Q22, qi cmat.FloatMatrix var zk0, zk1, dk0, dk1 float64 util.Partition2x2( &QTL, nil, nil, &QBR /**/, Q, 0, 0, util.PTOPLEFT) for m(&QBR) > 0 { util.Repartition2x2to3x3(&QTL, &Q00, nil, nil, nil, &q11, &q12, nil, &q21, &Q22 /**/, Q, 1, util.PBOTTOMRIGHT) //--------------------------------------------------------------- k := m(&Q00) zk0 = z.GetAt(k) dk0 = q11.Get(0, 0) q11.Set(0, 0, zk0/dk0) for i := 0; i < q12.Len(); i++ { zk1 = z.GetAt(k + i + 1) dk0 = q12.GetAt(i) dk1 = q21.GetAt(i) q12.SetAt(i, zk0/dk1) q21.SetAt(i, zk1/dk0) } //--------------------------------------------------------------- util.Continue3x3to2x2( &QTL, nil, nil, &QBR /**/, &Q00, &q11, &Q22 /**/, Q, util.PBOTTOMRIGHT) } // scale column eigenvectors for k := 0; k < z.Len(); k++ { qi.Column(Q, k) t := blasd.Nrm2(&qi) blasd.InvScale(&qi, t) } }
func test1(N int, beta float64, t *testing.T) { var sI cmat.FloatMatrix if N&0x1 != 0 { N = N + 1 } D := cmat.NewMatrix(N, 1) Z := cmat.NewMatrix(N, 1) Y := cmat.NewMatrix(N, 1) V := cmat.NewMatrix(N, 1) Q := cmat.NewMatrix(N, N) I := cmat.NewMatrix(N, N) D.SetAt(0, 1.0) Z.SetAt(0, 2.0) for i := 1; i < N-1; i++ { if i < N/2 { D.SetAt(i, 2.0-float64(N/2-i)*beta) } else { D.SetAt(i, 2.0+float64(i+1-N/2)*beta) } Z.SetAt(i, beta) } D.SetAt(N-1, 10.0/3.0) Z.SetAt(N-1, 2.0) w := blasd.Nrm2(Z) blasd.InvScale(Z, w) rho := 1.0 / (w * w) lapackd.TRDSecularSolveAll(Y, V, Q, D, Z, rho) lapackd.TRDSecularEigen(Q, V, nil) blasd.Mult(I, Q, Q, 1.0, 0.0, gomas.TRANSA) sI.Diag(I) sI.Add(-1.0) nrm := lapackd.NormP(I, lapackd.NORM_ONE) t.Logf("N=%d, beta=%e ||I - Q.T*Q||_1: %e\n", N, beta, nrm) }
/* From LAPACK/dlarfg.f * * Generates a real elementary reflector H of order n, such * that * * H * ( alpha ) = ( beta ), H**T * H = I. * ( x ) ( 0 ) * * where alpha and beta are scalars, and x is an (n-1)-element real * vector. H is represented in the form * * H = I - tau * ( 1 ) * ( 1 v**T ) , * ( v ) * * where tau is a real scalar and v is a real (n-1)-element * vector. * * If the elements of x are all zero, then tau = 0 and H is taken to be * the unit cmat. * * Otherwise 1 <= tau <= 2. */ func computeHouseholder(a11, x, tau *cmat.FloatMatrix) { // norm_x2 = ||x||_2 norm_x2 := blasd.Nrm2(x) if norm_x2 == 0.0 { tau.Set(0, 0, 0.0) return } alpha := a11.Get(0, 0) sign := 1.0 if math.Signbit(alpha) { sign = -1.0 } // beta = -(alpha / |alpha|) * ||alpha x|| // = -sign(alpha) * sqrt(alpha**2, norm_x2**2) beta := -sign * sqrtX2Y2(alpha, norm_x2) // x = x /(a11 - beta) blasd.InvScale(x, alpha-beta) tau.Set(0, 0, (beta-alpha)/beta) a11.Set(0, 0, beta) }