Esempio n. 1
0
// Simple and slow LQ decomposition with Givens rotations
func TestGivensLQ(t *testing.T) {
	var d cmat.FloatMatrix
	M := 149
	N := 167
	A := cmat.NewMatrix(M, N)
	A1 := cmat.NewCopy(A)

	ones := cmat.NewFloatConstSource(1.0)
	src := cmat.NewFloatNormSource()
	A.SetFrom(src)
	A0 := cmat.NewCopy(A)

	Qt := cmat.NewMatrix(N, N)
	d.Diag(Qt)
	d.SetFrom(ones)

	// R = G(n)...G(2)G(1)*A; Q = G(1).T*G(2).T...G(n).T ;  Q.T = G(n)...G(2)G(1)
	for i := 0; i < M; i++ {
		// zero elements right of diagonal
		for j := N - 2; j >= i; j-- {
			c, s, r := lapackd.ComputeGivens(A.Get(i, j), A.Get(i, j+1))
			A.Set(i, j, r)
			A.Set(i, j+1, 0.0)
			// apply rotation to this column starting from row i+1
			lapackd.ApplyGivensRight(A, j, j+1, i+1, M-i-1, c, s)
			// update Qt = G(k)*Qt
			lapackd.ApplyGivensRight(Qt, j, j+1, 0, N, c, s)
		}
	}
	// A = L*Q
	blasd.Mult(A1, A, Qt, 1.0, 0.0, gomas.TRANSB)
	blasd.Plus(A0, A1, 1.0, -1.0, gomas.NONE)
	nrm := lapackd.NormP(A0, lapackd.NORM_ONE)
	t.Logf("M=%d, N=%d ||A - L*G(1)..G(n)||_1: %e\n", M, N, nrm)
}
Esempio n. 2
0
/*
 * Compute
 *   B = B*diag(D).-1      flags & RIGHT == true
 *   B = diag(D).-1*B      flags & LEFT  == true
 *
 * If flags is LEFT (RIGHT) then element-wise divides columns (rows) of B with vector D.
 *
 * Arguments:
 *   B     M-by-N matrix if flags&RIGHT == true or N-by-M matrix if flags&LEFT == true
 *
 *   D     N element column or row vector or N-by-N matrix
 *
 *   flags Indicator bits, LEFT or RIGHT
 */
func SolveDiag(B, D *cmat.FloatMatrix, flags int, confs ...*gomas.Config) *gomas.Error {
	var c, d0 cmat.FloatMatrix
	var d *cmat.FloatMatrix

	conf := gomas.CurrentConf(confs...)
	d = D
	if !D.IsVector() {
		d0.Diag(D)
		d = &d0
	}
	dn := d0.Len()
	br, bc := B.Size()
	switch flags & (gomas.LEFT | gomas.RIGHT) {
	case gomas.LEFT:
		if br != dn {
			return gomas.NewError(gomas.ESIZE, "SolveDiag")
		}
		// scale rows;
		for k := 0; k < dn; k++ {
			c.Row(B, k)
			blasd.InvScale(&c, d.GetAt(k), conf)
		}
	case gomas.RIGHT:
		if bc != dn {
			return gomas.NewError(gomas.ESIZE, "SolveDiag")
		}
		// scale columns
		for k := 0; k < dn; k++ {
			c.Column(B, k)
			blasd.InvScale(&c, d.GetAt(k), conf)
		}
	}
	return nil
}
Esempio n. 3
0
func TestDTrmmUnitUpperRight(t *testing.T) {
	var d cmat.FloatMatrix
	N := 563
	K := 171

	A := cmat.NewMatrix(N, N)
	B := cmat.NewMatrix(K, N)
	B0 := cmat.NewMatrix(K, N)
	C := cmat.NewMatrix(K, N)

	zeros := cmat.NewFloatConstSource(0.0)
	ones := cmat.NewFloatConstSource(1.0)
	zeromean := cmat.NewFloatNormSource()

	A.SetFrom(zeromean, cmat.UPPER|cmat.UNIT)
	B.SetFrom(ones)
	B0.SetFrom(ones)
	// B = B*A
	blasd.MultTrm(B, A, 1.0, gomas.UPPER|gomas.RIGHT|gomas.UNIT)
	d.Diag(A).SetFrom(ones)
	blasd.Mult(C, B0, A, 1.0, 0.0, gomas.NONE)
	ok := C.AllClose(B)
	t.Logf("trmm(B, A, R|U|N|U) == gemm(C, B, TriUU(A))   : %v\n", ok)

	B.SetFrom(ones)
	// B = B*A.T
	d.SetFrom(zeros)
	blasd.MultTrm(B, A, 1.0, gomas.UPPER|gomas.RIGHT|gomas.TRANSA|gomas.UNIT)
	d.SetFrom(ones)
	blasd.Mult(C, B0, A, 1.0, 0.0, gomas.TRANSB)
	ok = C.AllClose(B)
	t.Logf("trmm(B, A, R|U|T|U) == gemm(C, B, TriUU(A).T) : %v\n", ok)
}
Esempio n. 4
0
func EigenSym(D, A, W *cmat.FloatMatrix, bits int, confs ...*gomas.Config) (err *gomas.Error) {

	var sD, sE, E, tau, Wred cmat.FloatMatrix
	var vv *cmat.FloatMatrix

	err = nil
	vv = nil
	conf := gomas.CurrentConf(confs...)

	if m(A) != n(A) || D.Len() != m(A) {
		err = gomas.NewError(gomas.ESIZE, "EigenSym")
		return
	}
	if bits&gomas.WANTV != 0 && W.Len() < 3*n(A) {
		err = gomas.NewError(gomas.EWORK, "EigenSym")
		return
	}

	if bits&(gomas.LOWER|gomas.UPPER) == 0 {
		bits = bits | gomas.LOWER
	}
	ioff := 1
	if bits&gomas.LOWER != 0 {
		ioff = -1
	}
	E.SetBuf(n(A)-1, 1, n(A)-1, W.Data())
	tau.SetBuf(n(A), 1, n(A), W.Data()[n(A)-1:])
	wrl := W.Len() - 2*n(A) - 1
	Wred.SetBuf(wrl, 1, wrl, W.Data()[2*n(A)-1:])

	// reduce to tridiagonal
	if err = TRDReduce(A, &tau, &Wred, bits, conf); err != nil {
		err.Update("EigenSym")
		return
	}
	sD.Diag(A)
	sE.Diag(A, ioff)
	blasd.Copy(D, &sD)
	blasd.Copy(&E, &sE)

	if bits&gomas.WANTV != 0 {
		if err = TRDBuild(A, &tau, &Wred, n(A), bits, conf); err != nil {
			err.Update("EigenSym")
			return
		}
		vv = A
	}

	// resize workspace
	wrl = W.Len() - n(A) - 1
	Wred.SetBuf(wrl, 1, wrl, W.Data()[n(A)-1:])

	if err = TRDEigen(D, &E, vv, &Wred, bits, conf); err != nil {
		err.Update("EigenSym")
		return
	}
	return
}
Esempio n. 5
0
/*
 * Unblocked code for generating M by N matrix Q with orthogonal columns which
 * are defined as the last N columns of the product of K first elementary
 * reflectors.
 *
 * Parameter nk is last nk elementary reflectors that are not used in computing
 * the matrix Q. Parameter mk length of the first unused elementary reflectors
 * First nk columns are zeroed and subdiagonal mk-nk is set to unit.
 *
 * Compatible with lapack.DORG2L subroutine.
 */
func unblkBuildQL(A, Tvec, W *cmat.FloatMatrix, mk, nk int, mayClear bool) {
	var ATL, ATR, ABL, ABR cmat.FloatMatrix
	var A00, a01, a10, a11, a21, A22 cmat.FloatMatrix
	var tT, tB cmat.FloatMatrix
	var t0, tau1, t2, w12, D cmat.FloatMatrix

	// (mk, nk) = (rows, columns) of upper left partition
	util.Partition2x2(
		&ATL, &ATR,
		&ABL, &ABR, A, mk, nk, util.PTOPLEFT)
	util.Partition2x1(
		&tT,
		&tB, Tvec, nk, util.PTOP)

	// zero the left side
	if nk > 0 && mayClear {
		blasd.Scale(&ABL, 0.0)
		blasd.Scale(&ATL, 0.0)
		D.Diag(&ATL, nk-mk)
		blasd.Add(&D, 1.0)
	}

	for m(&ABR) > 0 && n(&ABR) > 0 {
		util.Repartition2x2to3x3(&ATL,
			&A00, &a01, nil,
			&a10, &a11, nil,
			nil, &a21, &A22, A, 1, util.PBOTTOMRIGHT)
		util.Repartition2x1to3x1(&tT,
			&t0,
			&tau1,
			&t2, Tvec, 1, util.PBOTTOM)
		// ------------------------------------------------------
		w12.SubMatrix(W, 0, 0, a10.Len(), 1)
		applyHouseholder2x1(&tau1, &a01, &a10, &A00, &w12, gomas.LEFT)

		blasd.Scale(&a01, -tau1.Get(0, 0))
		a11.Set(0, 0, 1.0-tau1.Get(0, 0))

		// zero bottom elements
		blasd.Scale(&a21, 0.0)
		// ------------------------------------------------------
		util.Continue3x3to2x2(
			&ATL, &ATR,
			&ABL, &ABR, &A00, &a11, &A22, A, util.PBOTTOMRIGHT)
		util.Continue3x1to2x1(
			&tT,
			&tB, &t0, &tau1, Tvec, util.PBOTTOM)
	}
}
Esempio n. 6
0
func TestTrdMultUpper(t *testing.T) {
	var dt, et, da, ea cmat.FloatMatrix
	N := 843
	nb := 48
	conf := gomas.NewConf()
	conf.LB = nb

	A := cmat.NewMatrix(N, N)
	tau := cmat.NewMatrix(N, 1)
	src := cmat.NewFloatNormSource()
	// create symmetric matrix
	A.SetFrom(src, cmat.SYMM)
	A0 := cmat.NewCopy(A)

	W := lapackd.Workspace(lapackd.TRDReduceWork(A, conf))
	lapackd.TRDReduce(A, tau, W, gomas.UPPER, conf)

	// make tridiagonal matrix T
	T0 := cmat.NewMatrix(N, N)
	dt.Diag(T0)
	da.Diag(A)
	blasd.Copy(&dt, &da)

	ea.Diag(A, 1)
	et.Diag(T0, 1)
	blasd.Copy(&et, &ea)
	et.Diag(T0, -1)
	blasd.Copy(&et, &ea)
	T1 := cmat.NewCopy(T0)

	// compute Q*T*Q.T (unblocked)
	conf.LB = 0
	lapackd.TRDMult(T0, A, tau, W, gomas.LEFT|gomas.UPPER, conf)
	lapackd.TRDMult(T0, A, tau, W, gomas.RIGHT|gomas.TRANS|gomas.UPPER, conf)

	blasd.Plus(T0, A0, 1.0, -1.0, gomas.NONE)
	nrm := lapackd.NormP(T0, lapackd.NORM_ONE)
	t.Logf("N=%d, unblk.||A - Q*T*Q.T||_1: %e\n", N, nrm)

	// compute Q*T*Q.T (blocked)
	conf.LB = nb
	W = lapackd.Workspace(lapackd.TRDMultWork(A, gomas.LEFT|gomas.UPPER, conf))
	lapackd.TRDMult(T1, A, tau, W, gomas.LEFT|gomas.UPPER, conf)
	lapackd.TRDMult(T1, A, tau, W, gomas.RIGHT|gomas.TRANS|gomas.UPPER, conf)

	blasd.Plus(T1, A0, 1.0, -1.0, gomas.NONE)
	nrm = lapackd.NormP(T1, lapackd.NORM_ONE)
	t.Logf("N=%d,   blk.||A - Q*T*Q.T||_1: %e\n", N, nrm)
}
Esempio n. 7
0
/*
 * Unblocked code for generating M by N matrix Q with orthogonal columns which
 * are defined as the first N columns of the product of K first elementary
 * reflectors.
 *
 * Parameters nk = n(A)-K, mk = m(A)-K define the initial partitioning of
 * matrix A.
 *
 *  Q = H(k)H(k-1)...H(1)  , 0 < k <= M, where H(i) = I - tau*v*v.T
 *
 * Computation is ordered as H(k)*H(k-1)...*H(1)*I ie. from bottom to top.
 *
 * If k < M rows k+1:M are cleared and diagonal entries [k+1:M,k+1:M] are
 * set to unit. Then the matrix Q is generated by right multiplying elements below
 * of i'th elementary reflector H(i).
 *
 * Compatible to lapack.xORG2L subroutine.
 */
func unblkBuildLQ(A, Tvec, W *cmat.FloatMatrix, mk, nk int, mayClear bool) {
	var ATL, ATR, ABL, ABR cmat.FloatMatrix
	var A00, a10, a11, a12, a21, A22 cmat.FloatMatrix
	var tT, tB cmat.FloatMatrix
	var t0, tau1, t2, w12, D cmat.FloatMatrix

	util.Partition2x2(
		&ATL, &ATR,
		&ABL, &ABR, A, mk, nk, util.PBOTTOMRIGHT)
	util.Partition2x1(
		&tT,
		&tB, Tvec, mk, util.PBOTTOM)

	// zero the bottom part
	if mk > 0 && mayClear {
		blasd.Scale(&ABL, 0.0)
		blasd.Scale(&ABR, 0.0)
		D.Diag(&ABR)
		blasd.Add(&D, 1.0)
	}

	for m(&ATL) > 0 && n(&ATL) > 0 {
		util.Repartition2x2to3x3(&ATL,
			&A00, nil, nil,
			&a10, &a11, &a12,
			nil, &a21, &A22, A, 1, util.PTOPLEFT)
		util.Repartition2x1to3x1(&tT,
			&t0,
			&tau1,
			&t2, Tvec, 1, util.PTOP)
		// ------------------------------------------------------

		w12.SubMatrix(W, 0, 0, a21.Len(), 1)
		applyHouseholder2x1(&tau1, &a12, &a21, &A22, &w12, gomas.RIGHT)

		blasd.Scale(&a12, -tau1.Get(0, 0))
		a11.Set(0, 0, 1.0-tau1.Get(0, 0))

		// zero
		blasd.Scale(&a10, 0.0)
		// ------------------------------------------------------
		util.Continue3x3to2x2(
			&ATL, &ATR,
			&ABL, &ABR, &A00, &a11, &A22, A, util.PTOPLEFT)
		util.Continue3x1to2x1(
			&tT,
			&tB, &t0, &tau1, Tvec, util.PTOP)
	}
}
Esempio n. 8
0
func TestQLBuildwithK(t *testing.T) {
	var dc cmat.FloatMatrix
	M := 711
	N := 707
	K := 691
	lb := 36
	conf := gomas.NewConf()

	A := cmat.NewMatrix(M, N)
	src := cmat.NewFloatNormSource()
	A.SetFrom(src)
	tau := cmat.NewMatrix(N, 1)

	W := cmat.NewMatrix(M+N, 1)
	C := cmat.NewMatrix(N, N)

	conf.LB = lb
	lapackd.QLFactor(A, tau, W, conf)
	A1 := cmat.NewCopy(A)

	conf.LB = 0
	lapackd.QLBuild(A, tau, W, K, conf)
	blasd.Mult(C, A, A, 1.0, 0.0, gomas.TRANSA, conf)
	dc.Diag(C)
	blasd.Add(&dc, -1.0)
	if N < 10 {
		t.Logf("unblk.QLBuild Q:\n%v\n", A)
		t.Logf("unblk.QLBuild Q.T*Q:\n%v\n", C)
	}
	n0 := lapackd.NormP(C, lapackd.NORM_ONE)

	conf.LB = lb
	W1 := lapackd.Workspace(lapackd.QLBuildWork(A1, conf))
	lapackd.QLBuild(A1, tau, W1, K, conf)
	if N < 10 {
		t.Logf("blk.QLBuild Q:\n%v\n", A1)
	}
	// compute: I - Q.T*Q
	blasd.Mult(C, A1, A1, 1.0, 0.0, gomas.TRANSA, conf)
	blasd.Add(&dc, -1.0)
	n1 := lapackd.NormP(C, lapackd.NORM_ONE)

	blasd.Plus(A, A1, 1.0, -1.0, gomas.NONE)
	n2 := lapackd.NormP(A, lapackd.NORM_ONE)

	t.Logf("M=%d, N=%d, K=%d ||unblk.QLBuild(A) - blk.QLBuild(A)||_1 :%e\n", M, N, K, n2)
	t.Logf("unblk M=%d, N=%d, K=%d ||Q.T*Q - I||_1 : %e\n", M, N, K, n0)
	t.Logf("blk   M=%d, N=%d, K=%d ||Q.T*Q - I||_1 : %e\n", M, N, K, n1)
}
Esempio n. 9
0
func TestLQBuild(t *testing.T) {
	var dc cmat.FloatMatrix

	M := 877
	N := 913
	K := 831
	lb := 48
	conf := gomas.NewConf()
	_ = lb

	A := cmat.NewMatrix(M, N)
	src := cmat.NewFloatNormSource()
	A.SetFrom(src)
	tau := cmat.NewMatrix(M, 1)
	W := cmat.NewMatrix(M, 1)
	C := cmat.NewMatrix(M, M)
	dc.Diag(C)

	conf.LB = lb
	lapackd.LQFactor(A, tau, W, conf)
	A1 := cmat.NewCopy(A)

	conf.LB = 0
	lapackd.LQBuild(A, tau, W, K, conf)
	if N < 10 {
		t.Logf("unblk.LQBuild Q:\n%v\n", A)
	}
	blasd.Mult(C, A, A, 1.0, 0.0, gomas.TRANSB, conf)
	blasd.Add(&dc, -1.0)
	n0 := lapackd.NormP(C, lapackd.NORM_ONE)

	conf.LB = lb
	W2 := lapackd.Workspace(lapackd.LQBuildWork(A, conf))
	lapackd.LQBuild(A1, tau, W2, K, conf)
	if N < 10 {
		t.Logf("blk.LQBuild Q:\n%v\n", A1)
	}
	blasd.Mult(C, A1, A1, 1.0, 0.0, gomas.TRANSB, conf)
	blasd.Add(&dc, -1.0)
	n1 := lapackd.NormP(C, lapackd.NORM_ONE)

	blasd.Plus(A, A1, 1.0, -1.0, gomas.NONE)
	n2 := lapackd.NormP(A, lapackd.NORM_ONE)

	t.Logf("M=%d, N=%d, K=%d ||unblk.LQBuild(A) - blk.LQBuild(A)||_1 :%e\n", M, N, K, n2)
	t.Logf("unblk M=%d, N=%d, K=%d ||I - Q*Q.T||_1 : %e\n", M, N, K, n0)
	t.Logf("  blk M=%d, N=%d, K=%d ||I - Q*Q.T||_1 : %e\n", M, N, K, n1)
}
Esempio n. 10
0
func test_trdevd(N, flags, kind int, verbose bool, t *testing.T) {
	var At, sD, sE, tmp cmat.FloatMatrix

	A0 := cmat.NewMatrix(N, N)
	desc := setTrdDiagonals(A0, kind)
	At.SubMatrix(A0, 0, 0, N, N)
	sD.Diag(A0, 0)
	sE.Diag(A0, 1)
	D := cmat.NewCopy(&sD)
	E := cmat.NewCopy(&sE)

	V := cmat.NewMatrix(N, N)
	sD.Diag(V, 0)
	sD.Add(1.0)

	W := cmat.NewMatrix(4*N, 1)
	C := cmat.NewMatrix(N, N)

	if verbose && N < 10 {
		t.Logf("A0:\n%v\n", A0.ToString("%6.3f"))
		t.Logf("V.pre:\n%v\n", V.ToString("%6.3f"))
	}
	lapackd.TRDEigen(D, E, V, W, flags|gomas.WANTV)
	for k := 0; k < N-1; k++ {
		if E.GetAt(k) != 0.0 {
			t.Logf("E[%d] != 0.0 (%e)\n", k, E.GetAt(k))
		}
	}

	blasd.Mult(C, V, V, 1.0, 0.0, gomas.TRANSB)
	sD.Diag(C)
	sD.Add(-1.0)
	nrmv := lapackd.NormP(C, lapackd.NORM_ONE)

	blasd.Mult(C, V, A0, 1.0, 0.0, gomas.TRANSA)
	blasd.Mult(&At, C, V, 1.0, 0.0, gomas.NONE)
	if verbose && N < 10 {
		t.Logf("D:\n%v\n", asRow(&tmp, D).ToString("%6.3f"))
		t.Logf("V:\n%v\n", V.ToString("%6.3f"))
		t.Logf("V.T*A*V\n%v\n", At.ToString("%6.3f"))
	}
	sD.Diag(&At)
	blasd.Axpy(&sD, D, -1.0)
	nrma := lapackd.NormP(&At, lapackd.NORM_ONE)

	t.Logf("N=%d [%s] ||V.T*A*V - eigen(A)||_1: %e\n", N, desc, nrma)
	t.Logf("  ||I - V.T*V||_1: %e\n", nrmv)
}
Esempio n. 11
0
func TestQRBuild(t *testing.T) {
	var d cmat.FloatMatrix

	M := 911
	N := 899
	K := 873
	lb := 36
	conf := gomas.NewConf()

	A := cmat.NewMatrix(M, N)
	src := cmat.NewFloatNormSource()
	A.SetFrom(src)
	tau := cmat.NewMatrix(N, 1)
	W := cmat.NewMatrix(N+M, 1)

	C := cmat.NewMatrix(N, N)
	d.Diag(C)

	conf.LB = lb
	lapackd.QRFactor(A, tau, W, conf)
	A1 := cmat.NewCopy(A)

	conf.LB = 0
	lapackd.QRBuild(A, tau, W, K, conf)

	blasd.Mult(C, A, A, 1.0, 0.0, gomas.TRANSA, conf)
	blasd.Add(&d, -1.0)
	n0 := lapackd.NormP(C, lapackd.NORM_ONE)

	conf.LB = lb
	W2 := lapackd.Workspace(lapackd.QRBuildWork(A, conf))
	lapackd.QRBuild(A1, tau, W2, K, conf)

	blasd.Mult(C, A1, A1, 1.0, 0.0, gomas.TRANSA, conf)
	blasd.Add(&d, -1.0)
	n1 := lapackd.NormP(C, lapackd.NORM_ONE)

	blasd.Plus(A, A1, 1.0, -1.0, gomas.NONE)
	n2 := lapackd.NormP(A, lapackd.NORM_ONE)

	t.Logf("M=%d, N=%d, K=%d ||unblk.QRBuild(A) - blk.QRBuild(A)||_1 :%e\n", M, N, K, n2)
	t.Logf("unblk M=%d, N=%d, K=%d ||I - Q.T*Q||_1: %e\n", M, N, K, n0)
	t.Logf("  blk M=%d, N=%d, K=%d ||I - Q.T*Q||_1: %e\n", M, N, K, n1)
}
Esempio n. 12
0
func testEigen(N int, bits int, t *testing.T) {
	var A, A0, W, D, V *cmat.FloatMatrix
	var sD cmat.FloatMatrix
	var s string = "lower"

	if bits&gomas.UPPER != 0 {
		s = "upper"
	}

	wsize := N * N
	if wsize < 100 {
		wsize = 100
	}

	D = cmat.NewMatrix(N, 1)
	A = cmat.NewMatrix(N, N)
	V = cmat.NewMatrix(N, N)

	src := cmat.NewFloatNormSource()
	A.SetFrom(src, cmat.SYMM)
	A0 = cmat.NewCopy(A)
	W = cmat.NewMatrix(wsize, 1)

	if err := lapackd.EigenSym(D, A, W, bits|gomas.WANTV); err != nil {
		t.Errorf("EigenSym error: %v\n", err)
		return
	}

	// ||I - V.T*V||
	sD.Diag(V)
	blasd.Mult(V, A, A, 1.0, 0.0, gomas.TRANSA)
	blasd.Add(&sD, -1.0)
	nrm1 := lapackd.NormP(V, lapackd.NORM_ONE)

	// left vectors are M-by-N
	V.Copy(A)
	lapackd.MultDiag(V, D, gomas.RIGHT)
	blasd.Mult(A0, V, A, -1.0, 1.0, gomas.TRANSB)
	nrm2 := lapackd.NormP(A0, lapackd.NORM_ONE)

	t.Logf("N=%d, [%s] ||A - V*D*V.T||_1 :%e\n", N, s, nrm2)
	t.Logf("  ||I - V.T*V||_1 : %e\n", nrm1)
}
Esempio n. 13
0
/*
 * Generic rank update of diagonal matrix.
 *   diag(D) = diag(D) + alpha * x * y.T
 *
 * Arguments:
 *   D     N element column or row vector or N-by-N matrix
 *
 *   x, y  N element vectors
 *
 *   alpha scalar
 */
func MVUpdateDiag(D, x, y *cmat.FloatMatrix, alpha float64, confs ...*gomas.Config) *gomas.Error {
	var d *cmat.FloatMatrix
	var d0 cmat.FloatMatrix

	if !x.IsVector() || !y.IsVector() {
		return gomas.NewError(gomas.ENEED_VECTOR, "MvUpdateDiag")
	}

	d = D
	if !D.IsVector() {
		d0.Diag(D)
		d = &d0
	}

	for k := 0; k < d.Len(); k++ {
		val := d.GetAt(k)
		val += x.GetAt(k) * y.GetAt(k) * alpha
		d.SetAt(k, val)
	}
	return nil
}
Esempio n. 14
0
func TestDTrmmUnitUpper(t *testing.T) {
	var d cmat.FloatMatrix
	N := 563
	K := 171

	A := cmat.NewMatrix(N, N)
	B := cmat.NewMatrix(N, K)
	B0 := cmat.NewMatrix(N, K)
	C := cmat.NewMatrix(N, K)

	zeros := cmat.NewFloatConstSource(0.0)
	ones := cmat.NewFloatConstSource(1.0)
	zeromean := cmat.NewFloatNormSource()

	A.SetFrom(zeromean, cmat.UPPER|cmat.UNIT)
	B.SetFrom(ones)
	B0.SetFrom(ones)
	// B = A*B
	blasd.MultTrm(B, A, 1.0, gomas.UPPER|gomas.LEFT|gomas.UNIT)
	d.Diag(A).SetFrom(ones)
	blasd.Mult(C, A, B0, 1.0, 0.0, gomas.NONE)
	ok := C.AllClose(B)
	t.Logf("trmm(B, A, L|U|N|U) == gemm(C, TriUU(A), B)   : %v\n", ok)

	B.SetFrom(ones)
	// B = A.T*B
	d.Diag(A).SetFrom(zeros)
	blasd.MultTrm(B, A, 1.0, gomas.UPPER|gomas.LEFT|gomas.TRANSA|gomas.UNIT)
	d.Diag(A).SetFrom(ones)
	blasd.Mult(C, A, B0, 1.0, 0.0, gomas.TRANSA)
	ok = C.AllClose(B)
	t.Logf("trmm(B, A, L|U|T|U) == gemm(C, TriUU(A).T, B) : %v\n", ok)
}
Esempio n. 15
0
func setDiagonals(A *cmat.FloatMatrix, offdiag, kind int) string {
	var sD, sE cmat.FloatMatrix
	var desc string

	switch kind {
	case 2:
		desc = "middle"
	case 1:
		desc = "top   "
	default:
		desc = "bottom"
	}

	sD.Diag(A, 0)
	sE.Diag(A, offdiag)
	N := sD.Len()
	for k := 0; k < N; k++ {
		if k < N-1 {
			sE.SetAt(k, 1.0)
		}
		switch kind {
		case 2: // midheavy
			if k < N/2 {
				sD.SetAt(k, float64(k+1))
			} else {
				sD.SetAt(k, float64(N-k))
			}
			break
		case 1: // top heavy
			sD.SetAt(N-1-k, float64(k+1))
			break
		default: // bottom heavy
			sD.SetAt(k, float64(k+1))
			break
		}
	}
	return desc
}
Esempio n. 16
0
// Simple and slow QR decomposition with Givens rotations
func TestGivensQR(t *testing.T) {
	var d cmat.FloatMatrix
	M := 181
	N := 159
	A := cmat.NewMatrix(M, N)
	A1 := cmat.NewCopy(A)

	ones := cmat.NewFloatConstSource(1.0)
	src := cmat.NewFloatNormSource()
	A.SetFrom(src)
	A0 := cmat.NewCopy(A)

	Qt := cmat.NewMatrix(M, M)
	d.Diag(Qt)
	d.SetFrom(ones)

	// R = G(n)...G(2)G(1)*A; Q = G(1).T*G(2).T...G(n).T ;  Q.T = G(n)...G(2)G(1)

	// for all columns ...
	for j := 0; j < N; j++ {
		// ... zero elements below diagonal, starting from bottom
		for i := M - 2; i >= j; i-- {
			c, s, r := lapackd.ComputeGivens(A.Get(i, j), A.Get(i+1, j))
			A.Set(i, j, r)
			A.Set(i+1, j, 0.0)
			// apply rotations on this row starting from column j, N-j column
			lapackd.ApplyGivensLeft(A, i, i+1, j+1, N-j-1, c, s)
			// update Qt = G(k)*Qt
			lapackd.ApplyGivensLeft(Qt, i, i+1, 0, M, c, s)
		}
	}
	// check: A = Q*R
	blasd.Mult(A1, Qt, A, 1.0, 0.0, gomas.TRANSA)
	blasd.Plus(A0, A1, 1.0, -1.0, gomas.NONE)
	nrm := lapackd.NormP(A0, lapackd.NORM_ONE)
	t.Logf("M=%d, N=%d ||A - G(n)..G(1)*R||_1: %e\n", M, N, nrm)
}
Esempio n. 17
0
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)
}
Esempio n. 18
0
func TestBiredWide(t *testing.T) {
	N := 811
	M := 693
	nb := 32
	conf := gomas.NewConf()
	conf.LB = 0
	ediag := -1

	zeromean := cmat.NewFloatNormSource()
	A := cmat.NewMatrix(M, N)
	A.SetFrom(zeromean)
	A0 := cmat.NewCopy(A)

	tauq := cmat.NewMatrix(N, 1)
	taup := cmat.NewMatrix(N, 1)

	W := lapackd.Workspace(M + N)
	lapackd.BDReduce(A, tauq, taup, W, conf)

	var D, E, Bd, Be cmat.FloatMatrix
	D.Diag(A)
	E.Diag(A, ediag)

	B := cmat.NewMatrix(M, N)
	Bd.Diag(B)
	Be.Diag(B, ediag)
	blasd.Copy(&Bd, &D)
	blasd.Copy(&Be, &E)

	Bt := cmat.NewMatrix(N, M)
	blasd.Transpose(Bt, B)

	conf.LB = nb
	W0 := lapackd.Workspace(lapackd.BDMultWork(B, conf))
	lapackd.BDMult(B, A, tauq, W0, gomas.MULTQ|gomas.LEFT, conf)
	lapackd.BDMult(Bt, A, tauq, W0, gomas.MULTQ|gomas.RIGHT|gomas.TRANS, conf)

	lapackd.BDMult(B, A, taup, W0, gomas.MULTP|gomas.RIGHT|gomas.TRANS, conf)
	lapackd.BDMult(Bt, A, taup, W0, gomas.MULTP|gomas.LEFT, conf)

	blasd.Plus(B, A0, 1.0, -1.0, gomas.NONE)
	nrm := lapackd.NormP(B, lapackd.NORM_ONE)
	t.Logf("M=%d, N=%d ||A - Q*B*P.T||_1   : %e\n", M, N, nrm)
	blasd.Plus(Bt, A0, 1.0, -1.0, gomas.TRANSB)
	nrm = lapackd.NormP(Bt, lapackd.NORM_ONE)
	t.Logf("M=%d, N=%d ||A.T - P*B.T*Q.T||_1 : %e\n", M, N, nrm)
}
Esempio n. 19
0
// test: C = C*Q.T
func TestQLMultRightTrans(t *testing.T) {
	var d, di0, di1 cmat.FloatMatrix
	M := 891
	N := 853
	lb := 36
	conf := gomas.NewConf()

	A := cmat.NewMatrix(M, N)
	src := cmat.NewFloatNormSource()
	A.SetFrom(src)

	C0 := cmat.NewMatrix(N, M)
	d.Diag(C0, M-N)
	ones := cmat.NewFloatConstSource(1.0)
	d.SetFrom(ones)
	C1 := cmat.NewCopy(C0)

	I0 := cmat.NewMatrix(N, N)
	I1 := cmat.NewCopy(I0)
	di0.Diag(I0)
	di1.Diag(I1)

	tau := cmat.NewMatrix(N, 1)
	W := cmat.NewMatrix(lb*(M+N), 1)

	conf.LB = lb
	lapackd.QLFactor(A, tau, W, conf)

	conf.LB = 0
	lapackd.QLMult(C0, A, tau, W, gomas.RIGHT|gomas.TRANS, conf)
	// I = Q*Q.T - I
	blasd.Mult(I0, C0, C0, 1.0, 0.0, gomas.TRANSB, conf)
	blasd.Add(&di0, -1.0)
	n0 := lapackd.NormP(I0, lapackd.NORM_ONE)

	conf.LB = lb
	lapackd.QLMult(C1, A, tau, W, gomas.RIGHT|gomas.TRANS, conf)
	// I = Q*Q.T - I
	blasd.Mult(I1, C1, C1, 1.0, 0.0, gomas.TRANSB, conf)
	blasd.Add(&di1, -1.0)
	n1 := lapackd.NormP(I1, lapackd.NORM_ONE)

	if N < 10 {
		t.Logf("unblk C0*Q:\n%v\n", C0)
		t.Logf("blk. C2*Q:\n%v\n", C1)
	}
	blasd.Plus(C0, C1, 1.0, -1.0, gomas.NONE)
	n2 := lapackd.NormP(C0, lapackd.NORM_ONE)

	t.Logf("M=%d, N=%d ||unblk.QLMult(C) - blk.QLMult(C)||_1: %e\n", M, N, n2)
	t.Logf("unblk M=%d, N=%d ||I - Q*Q.T||_1: %e\n", M, N, n0)
	t.Logf("blk   M=%d, N=%d ||I - Q*Q.T||_1: %e\n", M, N, n1)
}
Esempio n. 20
0
// Compute SVD when m(A) >= n(A)
func svdTall(S, U, V, A, W *cmat.FloatMatrix, bits int, conf *gomas.Config) (err *gomas.Error) {
	var uu, vv *cmat.FloatMatrix
	var tauq, taup, Wred, sD, sE, R, Un cmat.FloatMatrix

	if (bits & (gomas.WANTU | gomas.WANTV)) != 0 {
		if W.Len() < 4*n(A) {
			err = gomas.NewError(gomas.ESIZE, "SVD")
			return
		}
	}
	tauq.SetBuf(n(A), 1, n(A), W.Data())
	taup.SetBuf(n(A)-1, 1, n(A)-1, W.Data()[tauq.Len():])
	wrl := W.Len() - 2*n(A) - 1
	Wred.SetBuf(wrl, 1, wrl, W.Data()[2*n(A)-1:])

	if svdCrossover(m(A), n(A)) {
		goto do_m_much_bigger
	}

	// reduce to bidiagonal form
	if err = BDReduce(A, &tauq, &taup, &Wred, conf); err != nil {
		return
	}

	sD.Diag(A)
	sE.Diag(A, 1)
	blasd.Copy(S, &sD)

	// left vectors
	if bits&gomas.WANTU != 0 {
		if n(U) == n(A) {
			// U is M-by-N; copy and make lower triangular
			U.Copy(A)
			cmat.TriL(U, 0)
			if err = BDBuild(U, &tauq, &Wred, n(U), gomas.WANTQ, conf); err != nil {
				return
			}
		} else {
			// U is M-by-M
			eye := cmat.FloatDiagonalSource{1.0}
			U.SetFrom(&eye, cmat.SYMM)
			if err = BDMult(U, A, &tauq, &Wred, gomas.MULTQ|gomas.RIGHT, conf); err != nil {
				return
			}
		}
		uu = U
	}
	// right vectors
	if bits&gomas.WANTV != 0 {
		R.SubMatrix(A, 0, 0, n(A), n(A))
		V.Copy(&R)
		cmat.TriU(V, 0)
		if err = BDBuild(V, &taup, &Wred, m(V), gomas.WANTP, conf); err != nil {
			return
		}
		vv = V
	}
	err = BDSvd(S, &sE, uu, vv, W, bits|gomas.UPPER)
	return

do_m_much_bigger:
	// M >> N here; first use QR factorization
	if err = QRFactor(A, &tauq, &Wred, conf); err != nil {
		return
	}
	if bits&gomas.WANTU != 0 {
		if n(U) == n(A) {
			U.Copy(A)
			if err = QRBuild(U, &tauq, &Wred, n(U), conf); err != nil {
				return
			}
		} else {
			// U is M-by-M
			eye := cmat.FloatDiagonalSource{1.0}
			U.SetFrom(&eye, cmat.SYMM)
			if err = QRMult(U, A, &tauq, &Wred, gomas.LEFT, conf); err != nil {
				return
			}
		}
	}
	R.SubMatrix(A, 0, 0, n(A), n(A))
	cmat.TriU(&R, 0)

	// bidiagonal reduce
	if err = BDReduce(&R, &tauq, &taup, &Wred, conf); err != nil {
		return
	}

	if bits&gomas.WANTU != 0 {
		Un.SubMatrix(U, 0, 0, m(A), n(A))
		if err = BDMult(&Un, &R, &tauq, &Wred, gomas.MULTQ|gomas.RIGHT, conf); err != nil {
			return
		}
		uu = U
	}
	if bits&gomas.WANTV != 0 {
		V.Copy(&R)
		if err = BDBuild(V, &taup, &Wred, m(V), gomas.WANTP, conf); err != nil {
			return
		}
		vv = V
	}

	sD.Diag(A)
	sE.Diag(A, 1)
	blasd.Copy(S, &sD)

	err = BDSvd(S, &sE, uu, vv, W, bits|gomas.UPPER, conf)
	return
}
Esempio n. 21
0
/*
 * Blocked version of Hessenberg reduction algorithm as presented in (1). This
 * version uses compact-WY transformation.
 *
 * Some notes:
 *
 * Elementary reflectors stored in [A11; A21].T are not on diagonal of A11. Update of
 * a block aligned with A11; A21 is as follow
 *
 * 1. Update from left Q(k)*C:
 *                                         c0   0                            c0
 * (I - Y*T*Y.T).T*C = C - Y*(C.T*Y)*T.T = C1 - Y1 * (C1.T.Y1+C2.T*Y2)*T.T = C1-Y1*W
 *                                         C2   Y2                           C2-Y2*W
 *
 * where W = (C1.T*Y1+C2.T*Y2)*T.T and first row of C is not affected by update
 *
 * 2. Update from right C*Q(k):
 *                                       0
 * C - C*Y*T*Y.T = c0;C1;C2 - c0;C1;C2 * Y1 *T*(0;Y1;Y2) = c0; C1-W*Y1; C2-W*Y2
 *                                       Y2
 * where  W = (C1*Y1 + C2*Y2)*T and first column of C is not affected
 *
 */
func blkHessGQvdG(A, Tvec, W *cmat.FloatMatrix, nb int, conf *gomas.Config) *gomas.Error {
	var ATL, ATR, ABL, ABR cmat.FloatMatrix
	var A00, A11, A12, A21, A22, A2 cmat.FloatMatrix
	var tT, tB, td cmat.FloatMatrix
	var t0, t1, t2, T cmat.FloatMatrix
	var V, VT, VB /*V0, V1, V2,*/, Y1, Y2, W0 cmat.FloatMatrix

	//fmt.Printf("blkHessGQvdG...\n")
	T.SubMatrix(W, 0, 0, conf.LB, conf.LB)
	V.SubMatrix(W, conf.LB, 0, m(A), conf.LB)
	td.Diag(&T)

	util.Partition2x2(
		&ATL, &ATR,
		&ABL, &ABR, A, 0, 0, util.PTOPLEFT)
	util.Partition2x1(
		&tT,
		&tB, Tvec, 0, util.PTOP)

	for m(&ABR) > nb+1 && n(&ABR) > nb {
		util.Repartition2x2to3x3(&ATL,
			&A00, nil, nil,
			nil, &A11, &A12,
			nil, &A21, &A22, A, nb, util.PBOTTOMRIGHT)
		util.Repartition2x1to3x1(&tT,
			&t0,
			&t1,
			&t2, Tvec, nb, util.PBOTTOM)

		util.Partition2x1(
			&VT,
			&VB, &V, m(&ATL), util.PTOP)
		// ------------------------------------------------------

		unblkBuildHessGQvdG(&ABR, &T, &VB, nil)
		blasd.Copy(&t1, &td)

		// m(Y) == m(ABR)-1, n(Y) == n(A11)
		Y1.SubMatrix(&ABR, 1, 0, n(&A11), n(&A11))
		Y2.SubMatrix(&ABR, 1+n(&A11), 0, m(&A21)-1, n(&A11))

		// [A01; A02] == ATR := ATR*(I - Y*T*Y.T)
		updateHessRightWY(&ATR, &Y1, &Y2, &T, &VT, conf)

		// A2 = [A12; A22].T
		util.Merge2x1(&A2, &A12, &A22)

		// A2 := A2 - VB*T*A21.T
		be := A21.Get(0, -1)
		A21.Set(0, -1, 1.0)
		blasd.MultTrm(&VB, &T, 1.0, gomas.UPPER|gomas.RIGHT)
		blasd.Mult(&A2, &VB, &A21, -1.0, 1.0, gomas.TRANSB, conf)
		A21.Set(0, -1, be)

		// A2 := (I - Y*T*Y.T).T * A2
		W0.SubMatrix(&V, 0, 0, n(&A2), n(&Y2))
		updateHessLeftWY(&A2, &Y1, &Y2, &T, &W0, conf)

		// ------------------------------------------------------
		util.Continue3x3to2x2(
			&ATL, &ATR,
			&ABL, &ABR, &A00, &A11, &A22, A, util.PBOTTOMRIGHT)
		util.Continue3x1to2x1(
			&tT,
			&tB, &t0, &t1, Tvec, util.PBOTTOM)
	}

	if m(&ABR) > 1 {
		// do the rest with unblocked
		util.Merge2x1(&A2, &ATR, &ABR)
		W0.SetBuf(m(A), 1, m(A), W.Data())
		unblkHessGQvdG(&A2, &tB, &W0, m(&ATR))
	}
	return nil
}
Esempio n. 22
0
/*
 * Blocked code for generating M by N matrix Q with orthogonal columns which
 * are defined as the last N columns of the product of K first elementary
 * reflectors.
 *
 * If the number K of elementary reflectors is not multiple of the blocking
 * factor lb, then unblocked code is used first to generate the upper left corner
 * of the matrix Q.
 *
 * Compatible with lapack.DORGQL subroutine.
 */
func blkBuildQL(A, Tvec, Twork, W *cmat.FloatMatrix, K, lb int, conf *gomas.Config) {
	var ATL, ATR, ABL, ABR, AL cmat.FloatMatrix
	var A00, A01, A10, A11, A21, A22 cmat.FloatMatrix
	var tT, tB cmat.FloatMatrix
	var t0, tau, t2, Wrk, D, T cmat.FloatMatrix

	nk := n(A) - K
	mk := m(A) - K
	uk := K % lb
	util.Partition2x2(
		&ATL, &ATR,
		&ABL, &ABR, A, mk+uk, nk+uk, util.PTOPLEFT)
	util.Partition2x1(
		&tT,
		&tB, Tvec, nk+uk, util.PTOP)

	// zero the left side
	if nk+uk > 0 {
		blasd.Scale(&ABL, 0.0)
		if uk > 0 {
			// number of reflectors is not multiple of blocking factor
			// do the first part with unblocked code.
			unblkBuildQL(&ATL, &tT, W, m(&ATL)-uk, n(&ATL)-uk, true)
		} else {
			// blocking factor is multiple of K
			blasd.Scale(&ATL, 0.0)
			D.Diag(&ATL)
			blasd.Add(&D, 1.0)
		}
	}

	for m(&ABR) > 0 && n(&ABR) > 0 {
		util.Repartition2x2to3x3(&ATL,
			&A00, &A01, nil,
			&A10, &A11, nil,
			nil, &A21, &A22, A, lb, util.PBOTTOMRIGHT)
		util.Repartition2x1to3x1(&tT,
			&t0,
			&tau,
			&t2, Tvec, lb, util.PBOTTOM)
		// ------------------------------------------------------
		util.Merge2x1(&AL, &A01, &A11)

		// build block reflector
		T.SubMatrix(Twork, 0, 0, n(&A11), n(&A11))
		unblkQLBlockReflector(&T, &AL, &tau)

		// update left side i.e. A10 and A00 with (I - Y*T*Y.T)
		ar, ac := A10.Size()
		Wrk.SubMatrix(W, 0, 0, ac, ar)
		updateQLLeft(&A10, &A00, &A11, &A01, &T, &Wrk, false, conf)

		// update current block
		unblkBuildQL(&AL, &tau, W, m(&A01), 0, false)

		// zero bottom rows
		blasd.Scale(&A21, 0.0)
		// ------------------------------------------------------
		util.Continue3x3to2x2(
			&ATL, &ATR,
			&ABL, &ABR, &A00, &A11, &A22, A, util.PBOTTOMRIGHT)
		util.Continue3x1to2x1(
			&tT,
			&tB, &t0, &tau, Tvec, util.PBOTTOM)
	}

}
Esempio n. 23
0
func blkBuildLQ(A, Tvec, Twork, W *cmat.FloatMatrix, K, lb int, conf *gomas.Config) {
	var ATL, ATR, ABL, ABR, AL cmat.FloatMatrix
	var A00, A10, A11, A12, A21, A22 cmat.FloatMatrix
	var tT, tB cmat.FloatMatrix
	var t0, tau, t2, Wrk, D, T cmat.FloatMatrix

	nk := n(A) - K
	mk := m(A) - K
	uk := K % lb
	util.Partition2x2(
		&ATL, &ATR,
		&ABL, &ABR, A, mk+uk, nk+uk, util.PBOTTOMRIGHT)
	util.Partition2x1(
		&tT,
		&tB, Tvec, mk+uk, util.PBOTTOM)

	// zero the bottom part __CHECK HERE: nk? or mk?
	if nk+uk > 0 {
		blasd.Scale(&ABL, 0.0)
		if uk > 0 {
			// number of reflectors is not multiple of blocking factor
			// do the first part with unblocked code.
			unblkBuildLQ(&ABR, &tB, W, m(&ABR)-uk, n(&ABR)-uk, true)
		} else {
			// blocking factor is multiple of K
			blasd.Scale(&ABR, 0.0)
			D.Diag(&ABR)
			blasd.Add(&D, 1.0)
		}
	}

	for m(&ATL) > 0 && n(&ATL) > 0 {
		util.Repartition2x2to3x3(&ATL,
			&A00, nil, nil,
			&A10, &A11, &A12,
			nil, &A21, &A22, A, lb, util.PTOPLEFT)
		util.Repartition2x1to3x1(&tT,
			&t0,
			&tau,
			&t2, Tvec, lb, util.PTOP)
		// ------------------------------------------------------
		util.Merge1x2(&AL, &A11, &A12)

		// build block reflector
		T.SubMatrix(Twork, 0, 0, n(&A11), n(&A11))
		unblkBlockReflectorLQ(&T, &AL, &tau)

		// update A21 and A22 with (I - Y*T*Y.T) from right
		ar, ac := A21.Size()
		Wrk.SubMatrix(W, 0, 0, ar, ac)
		updateRightLQ(&A21, &A22, &A11, &A12, &T, &Wrk, false, conf)

		// update current block
		unblkBuildLQ(&AL, &tau, W, 0, n(&A12), false)

		// zero top rows
		blasd.Scale(&A10, 0.0)
		// ------------------------------------------------------
		util.Continue3x3to2x2(
			&ATL, &ATR,
			&ABL, &ABR, &A00, &A11, &A22, A, util.PTOPLEFT)
		util.Continue3x1to2x1(
			&tT,
			&tB, &t0, &tau, Tvec, util.PTOP)
	}
}
Esempio n. 24
0
func test_bdsvd(N, flags, kind int, verbose bool, t *testing.T) {
	var At, sD, sE, tmp cmat.FloatMatrix

	uplo := "upper"
	offdiag := 1
	if flags&gomas.LOWER != 0 {
		offdiag = -1
		uplo = "lower"
	}
	A0 := cmat.NewMatrix(N, N)
	desc := setDiagonals(A0, offdiag, kind)
	At.SubMatrix(A0, 0, 0, N, N)
	sD.Diag(A0, 0)
	sE.Diag(A0, offdiag)
	D := cmat.NewCopy(&sD)
	E := cmat.NewCopy(&sE)

	// unit singular vectors
	U := cmat.NewMatrix(N, N)
	sD.Diag(U, 0)
	sD.Add(1.0)

	V := cmat.NewMatrix(N, N)
	sD.Diag(V, 0)
	sD.Add(1.0)

	W := cmat.NewMatrix(4*N, 1)
	C := cmat.NewMatrix(N, N)

	lapackd.BDSvd(D, E, U, V, W, flags|gomas.WANTU|gomas.WANTV)

	blasd.Mult(C, U, U, 1.0, 0.0, gomas.TRANSA)
	sD.Diag(C)
	sD.Add(-1.0)
	nrmu := lapackd.NormP(C, lapackd.NORM_ONE)

	blasd.Mult(C, V, V, 1.0, 0.0, gomas.TRANSB)
	sD.Add(-1.0)
	nrmv := lapackd.NormP(C, lapackd.NORM_ONE)

	blasd.Mult(C, U, A0, 1.0, 0.0, gomas.TRANSA)
	blasd.Mult(&At, C, V, 1.0, 0.0, gomas.TRANSB)
	if verbose && N < 10 {
		t.Logf("D:\n%v\n", asRow(&tmp, D))
		t.Logf("U:\n%v\n", U)
		t.Logf("V:\n%v\n", V)
		t.Logf("U.T*A*V\n%v\n", &At)
	}
	sD.Diag(&At)
	blasd.Axpy(&sD, D, -1.0)
	nrma := lapackd.NormP(&At, lapackd.NORM_ONE)

	t.Logf("N=%d [%s,%s] ||U.T*A*V - bdsvd(A)||_1: %e\n", N, uplo, desc, nrma)
	t.Logf("  ||I - U.T*U||_1: %e\n", nrmu)
	t.Logf("  ||I - V.T*V||_1: %e\n", nrmv)
}
Esempio n. 25
0
func svdWide(S, U, V, A, W *cmat.FloatMatrix, bits int, conf *gomas.Config) (err *gomas.Error) {
	var uu, vv *cmat.FloatMatrix
	var tauq, taup, Wred, sD, sE, L, Vm cmat.FloatMatrix

	if (bits & (gomas.WANTU | gomas.WANTV)) != 0 {
		if W.Len() < 4*n(A) {
			err = gomas.NewError(gomas.ESIZE, "SVD")
			return
		}
	}
	tauq.SetBuf(m(A)-1, 1, m(A)-1, W.Data())
	taup.SetBuf(m(A), 1, m(A), W.Data()[tauq.Len():])
	wrl := W.Len() - 2*m(A) - 1
	Wred.SetBuf(wrl, 1, wrl, W.Data()[2*m(A)-1:])

	if svdCrossover(n(A), m(A)) {
		goto do_n_much_bigger
	}

	// reduce to bidiagonal form
	if err = BDReduce(A, &tauq, &taup, &Wred, conf); err != nil {
		return
	}

	sD.Diag(A)
	sE.Diag(A, -1)
	blasd.Copy(S, &sD)

	// leftt vectors
	if bits&gomas.WANTU != 0 {
		L.SubMatrix(A, 0, 0, m(A), m(A))
		U.Copy(&L)
		cmat.TriL(U, 0)
		if err = BDBuild(U, &tauq, &Wred, m(U), gomas.WANTQ|gomas.LOWER, conf); err != nil {
			return
		}
		uu = U
	}
	// right vectors
	if bits&gomas.WANTV != 0 {
		if m(V) == m(A) {
			// V is M-by-N; copy and make upper triangular
			V.Copy(A)
			//cmat.TriU(V, 0)
			if err = BDBuild(V, &taup, &Wred, m(V), gomas.WANTP, conf); err != nil {
				return
			}
		} else {
			// V is N-by-N
			eye := cmat.FloatDiagonalSource{1.0}
			V.SetFrom(&eye, cmat.SYMM)
			err = BDMult(V, A, &taup, &Wred, gomas.MULTP|gomas.LEFT|gomas.TRANS, conf)
			if err != nil {
				return
			}
		}
		vv = V
	}
	err = BDSvd(S, &sE, uu, vv, W, bits|gomas.LOWER)
	return

do_n_much_bigger:
	// here N >> M, use LQ factor first
	if err = LQFactor(A, &taup, &Wred, conf); err != nil {
		return
	}
	if bits&gomas.WANTV != 0 {
		if m(V) == m(A) {
			V.Copy(A)
			if err = LQBuild(V, &taup, &Wred, m(A), conf); err != nil {
				return
			}
		} else {
			// V is N-by-N
			eye := cmat.FloatDiagonalSource{1.0}
			V.SetFrom(&eye, cmat.SYMM)
			if err = LQMult(V, A, &taup, &Wred, gomas.RIGHT, conf); err != nil {
				return
			}
		}
	}
	L.SubMatrix(A, 0, 0, m(A), m(A))
	cmat.TriL(&L, 0)

	// resize tauq/taup for UPPER bidiagonal reduction
	tauq.SetBuf(m(A), 1, m(A), W.Data())
	taup.SetBuf(m(A)-1, 1, m(A)-1, W.Data()[tauq.Len():])

	// bidiagonal reduce
	if err = BDReduce(&L, &tauq, &taup, &Wred, conf); err != nil {
		return
	}

	if bits&gomas.WANTV != 0 {
		Vm.SubMatrix(V, 0, 0, m(A), n(A))
		err = BDMult(&Vm, &L, &taup, &Wred, gomas.MULTP|gomas.LEFT|gomas.TRANS, conf)
		if err != nil {
			return
		}
		vv = V
	}
	if bits&gomas.WANTU != 0 {
		U.Copy(&L)
		if err = BDBuild(U, &tauq, &Wred, m(U), gomas.WANTQ, conf); err != nil {
			return
		}
		uu = U
	}

	sD.Diag(A)
	sE.Diag(A, 1)
	blasd.Copy(S, &sD)

	err = BDSvd(S, &sE, uu, vv, W, bits|gomas.UPPER, conf)
	return
}
Esempio n. 26
0
// test: M < N, U=[m,m] and V=[m,n] or V=[n,n] (square)
func testWide(M, N int, square bool, t *testing.T) {
	var A, A0, W, S, U, Uu, V, Vv *cmat.FloatMatrix
	var sD cmat.FloatMatrix
	var s string

	wsize := M * N
	if wsize < 100 {
		wsize = 100
	}

	S = cmat.NewMatrix(M, 1)
	A = cmat.NewMatrix(M, N)
	U = cmat.NewMatrix(M, M)
	Uu = cmat.NewMatrix(M, M)
	if square {
		V = cmat.NewMatrix(N, N)
		Vv = cmat.NewMatrix(N, N)
	} else {
		V = cmat.NewMatrix(M, N)
		Vv = cmat.NewMatrix(M, M)
	}

	src := cmat.NewFloatNormSource()
	A.SetFrom(src)
	A0 = cmat.NewCopy(A)
	W = cmat.NewMatrix(wsize, 1)

	if err := lapackd.SVD(S, U, V, A, W, gomas.WANTU|gomas.WANTV); err != nil {
		t.Errorf("SVD error: %v\n", err)
		return
	}

	// ||I - U.T*U||
	sD.Diag(Uu)
	blasd.Mult(Uu, U, U, 1.0, 0.0, gomas.TRANSA)
	blasd.Add(&sD, -1.0)
	nrm0 := lapackd.NormP(Uu, lapackd.NORM_ONE)

	// ||I - V*V.T||
	sD.Diag(Vv)
	blasd.Mult(Vv, V, V, 1.0, 0.0, gomas.TRANSB)
	blasd.Add(&sD, -1.0)
	nrm1 := lapackd.NormP(Vv, lapackd.NORM_ONE)

	if square {
		// right vectors are N-by-N
		Sg := cmat.NewMatrix(M, N)
		A1 := cmat.NewMatrix(M, N)
		sD.Diag(Sg)
		blasd.Copy(&sD, S)
		blasd.Mult(A1, Sg, V, 1.0, 0.0, gomas.NONE)
		blasd.Mult(A0, U, A1, -1.0, 1.0, gomas.NONE)
		s = "U=[m,m], V=[n,n]"
	} else {
		// right vectors are M-by-N
		lapackd.MultDiag(V, S, gomas.LEFT)
		blasd.Mult(A0, U, V, -1.0, 1.0, gomas.NONE)
		s = "U=[m,m], V=[m,n]"
	}
	nrm2 := lapackd.NormP(A0, lapackd.NORM_ONE)

	if N < 10 {
		t.Logf("A - U*S*V.T:\n%v\n", A0)
	}
	t.Logf("M=%d, N=%d, %s ||A - U*S*V.T||_1 :%e\n", M, N, s, nrm2)
	t.Logf("  ||I - U.T*U||_1 : %e\n", nrm0)
	t.Logf("  ||I - V*V.T||_1 : %e\n", nrm1)
}