func TestDSyr1(t *testing.T) { const N = 911 A := cmat.NewMatrix(N, N) X := cmat.NewMatrix(N, 1) B := cmat.NewMatrix(N, N) //ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatUniformSource(0.5, 2.0) A.SetFrom(zeromean, cmat.LOWER) X.SetFrom(zeromean) B.Copy(A) // B = A*B blasd.MVUpdate(B, X, X, 1.0) cmat.TriL(B, cmat.NONE) blasd.MVUpdateSym(A, X, 1.0, gomas.LOWER) ok := B.AllClose(A) t.Logf("MVUpdateSym(A, X, L) == TriL(MVUpdate(A, X, X)) : %v\n", ok) A.SetFrom(zeromean, cmat.UPPER) cmat.TriU(A, cmat.NONE) B.Copy(A) blasd.MVUpdate(B, X, X, 1.0) cmat.TriU(B, cmat.NONE) blasd.MVUpdateSym(A, X, 1.0, gomas.UPPER) ok = B.AllClose(A) t.Logf("MVUpdateSym(A, X, U) == TriU(MVUpdate(A, X, X)) : %v\n", ok) }
// QR decompose A, then compute ||A - (R.T*Q.T).T||_1, should be small func TestUnblkQRMultRight(t *testing.T) { M := 711 N := 593 A := cmat.NewMatrix(M, N) C := cmat.NewMatrix(N, M) tau := cmat.NewMatrix(N, 1) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean) A0 := cmat.NewCopy(A) conf := gomas.NewConf() conf.LB = 0 // QR = A = Q*R W := lapackd.Workspace(lapackd.QRFactorWork(A, conf)) lapackd.QRFactor(A, tau, W, conf) // C = transpose(TriU(QR)) = R.T C.Transpose(cmat.TriU(cmat.NewCopy(A), cmat.NONE)) // C = C*Q.T = R.T*Q.T W = lapackd.Workspace(lapackd.QRMultWork(C, gomas.RIGHT, conf)) err := lapackd.QRMult(C, A, tau, W, gomas.RIGHT|gomas.TRANS, conf) if err != nil { t.Logf("err: %v\n", err) } // A = A - QR blasd.Plus(A0, C, 1.0, -1.0, gomas.TRANSB) // ||A - Q*R||_1 nrm := lapackd.NormP(A0, lapackd.NORM_ONE) t.Logf("M=%d,N=%d ||A - (R.T*Q.T).T||_1: %e\n", M, N, nrm) }
// QR decompose A, then compute ||A - Q*R||_1, should be small func TestUnblkQRMultLeft(t *testing.T) { M := 711 N := 593 A := cmat.NewMatrix(M, N) tau := cmat.NewMatrix(N, 1) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean) A0 := cmat.NewCopy(A) conf := gomas.NewConf() conf.LB = 0 // QR = A = Q*R W := lapackd.Workspace(lapackd.QRFactorWork(A, conf)) lapackd.QRFactor(A, tau, W, conf) // C = TriU(QR) = R C := cmat.TriU(cmat.NewCopy(A), cmat.NONE) // C = Q*C W = lapackd.Workspace(lapackd.QRMultWork(C, gomas.LEFT, conf)) err := lapackd.QRMult(C, A, tau, W, gomas.LEFT, conf) if err != nil { t.Logf("err: %v\n", err) } // A = A - QR blasd.Plus(A0, C, 1.0, -1.0, gomas.NONE) // ||A - Q*R||_1 nrm := lapackd.NormP(A0, lapackd.NORM_ONE) t.Logf("M=%d,N=%d ||A - Q*R||_1: %e\n", M, N, nrm) }
func TestDSyr2(t *testing.T) { const N = 911 A := cmat.NewMatrix(N, N) X := cmat.NewMatrix(N, 1) Y := cmat.NewMatrix(N, 1) B := cmat.NewMatrix(N, N) ones := cmat.NewFloatConstSource(1.0) twos := cmat.NewFloatConstSource(2.0) zeromean := cmat.NewFloatUniformSource(0.5, 2.0) A.SetFrom(zeromean, cmat.LOWER) X.SetFrom(ones) Y.SetFrom(twos) B.Copy(A) // B = A*B blasd.MVUpdate(B, X, Y, 1.0) blasd.MVUpdate(B, Y, X, 1.0) cmat.TriL(B, cmat.NONE) blasd.MVUpdate2Sym(A, X, Y, 1.0, gomas.LOWER) ok := B.AllClose(A) if N < 10 { t.Logf("A:\n%v\n", A) t.Logf("B:\n%v\n", B) } t.Logf("MVUpdate2Sym(A, X, Y, L) == TriL(MVUpdate(A, X, Y);MVUpdate(A, Y, X)) : %v\n", ok) A.SetFrom(zeromean, cmat.UPPER) cmat.TriU(A, cmat.NONE) B.Copy(A) blasd.MVUpdate(B, X, Y, 1.0) blasd.MVUpdate(B, Y, X, 1.0) cmat.TriU(B, cmat.NONE) blasd.MVUpdate2Sym(A, X, Y, 1.0, gomas.UPPER) ok = B.AllClose(A) if N < 10 { t.Logf("A:\n%v\n", A) t.Logf("B:\n%v\n", B) } t.Logf("MVUpdate2Sym(A, X, Y, U) == TriU(MVUpdate(A, X, Y);MVUpdate(A, Y, X)) : %v\n", ok) }
func TestDSyrkUpper(t *testing.T) { var ok bool conf := gomas.NewConf() A := cmat.NewMatrix(N, N) A0 := cmat.NewMatrix(N, N) B := cmat.NewMatrix(N, K) Bt := cmat.NewMatrix(K, N) ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatUniformSource() _, _ = ones, zeromean A.SetFrom(ones, cmat.UPPER) A0.Copy(A) B.SetFrom(ones) Bt.Transpose(B) // B = A*B blasd.UpdateSym(A, B, 1.0, 1.0, gomas.UPPER, conf) blasd.Mult(A0, B, B, 1.0, 1.0, gomas.TRANSB) cmat.TriU(A0, cmat.NONE) ok = A0.AllClose(A) t.Logf("UpdateSym(A, B, U|N) == TriU(Mult(A, B, B.T)) : %v\n", ok) if N < 10 { t.Logf("UpdateSym(A, B)\n%v\n", A) t.Logf("Mult(A, B.T, B)\n%v\n", A0) } A.SetFrom(ones, cmat.UPPER) A0.Copy(A) blasd.UpdateSym(A, Bt, 1.0, 1.0, gomas.UPPER|gomas.TRANSA, conf) blasd.Mult(A0, Bt, Bt, 1.0, 1.0, gomas.TRANSA) cmat.TriU(A0, cmat.NONE) ok = A0.AllClose(A) t.Logf("UpdateSym(A, B, U|T) == TriU(Mult(A, B.T, B)) : %v\n", ok) if N < 10 { t.Logf("UpdateSym(A, B)\n%v\n", A) t.Logf("Mult(A, B.T, B)\n%v\n", A0) } }
func TestDSyrOther(t *testing.T) { const N = 911 var vec, As, Bs cmat.FloatMatrix P := N / 3 A := cmat.NewMatrix(P, P) X := cmat.NewMatrix(P, 1) B := cmat.NewMatrix(P, P) //ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatUniformSource(0.5, 2.0) A.SetFrom(zeromean, cmat.UPPER) X.SetFrom(zeromean) B.Copy(A) // update submatrices for i := 1; i < P; i++ { vec.SubMatrix(A, i-1, i, 1, P-i) As.SubMatrix(A, i, i) Bs.SubMatrix(B, i, i) // update with normal and symmetric blasd.MVUpdate(&Bs, &vec, &vec, 1.0) blasd.MVUpdateSym(&As, &vec, 1.0, gomas.UPPER) } // make normal update triangular and compare cmat.TriU(B, cmat.NONE) ok := B.AllClose(A) t.Logf("submatrix updates on upper triangular : %v\n", ok) A.SetFrom(zeromean, cmat.LOWER) cmat.TriL(A, cmat.NONE) B.Copy(A) // update submatrices for i := 1; i < P; i++ { vec.SubMatrix(A, i-1, i, 1, P-i) As.SubMatrix(A, i, i) Bs.SubMatrix(B, i, i) // update with normal and symmetric blasd.MVUpdate(&Bs, &vec, &vec, 1.0) blasd.MVUpdateSym(&As, &vec, 1.0, gomas.LOWER) } // make normal update triangular and compare cmat.TriL(B, cmat.NONE) ok = B.AllClose(A) t.Logf("submatrix updates on lower triangular : %v\n", ok) }
// QR decompose A, then compute ||A - Q*R||_1, should be small func TestMultQTLeft(t *testing.T) { M := 513 N := 477 nb := 16 A := cmat.NewMatrix(M, N) T := cmat.NewMatrix(nb, N) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean) A0 := cmat.NewCopy(A) conf := gomas.NewConf() conf.LB = nb //t.Logf("A0:\n%v\n", A0) // QR = A = Q*R W := lapackd.Workspace(lapackd.QRTFactorWork(A, conf)) lapackd.QRTFactor(A, T, W, conf) //t.Logf("T:\n%v\n", T) // C = TriU(QR) = R C := cmat.TriU(cmat.NewCopy(A), cmat.NONE) //t.Logf("R:\n%v\n", C) // C = Q*C W = lapackd.Workspace(lapackd.QRTMultWork(C, T, gomas.LEFT, conf)) err := lapackd.QRTMult(C, A, T, W, gomas.LEFT, conf) if err != nil { t.Logf("err: %v\n", err) } // A = A - QR blasd.Plus(A0, C, 1.0, -1.0, gomas.NONE) // ||A - Q*R||_1 nrm := lapackd.NormP(A0, lapackd.NORM_ONE) t.Logf("M=%d,N=%d ||A - Q*R||_1: %e\n", M, N, nrm) }
// 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 }