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) }
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) }
func TestDSyrkLower(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.LOWER) A0.Copy(A) B.SetFrom(ones) Bt.Transpose(B) // B = A*B blasd.UpdateSym(A, B, 1.0, 1.0, gomas.LOWER, conf) blasd.Mult(A0, B, B, 1.0, 1.0, gomas.TRANSB) cmat.TriL(A0, cmat.NONE) ok = A0.AllClose(A) t.Logf("UpdateSym(A, B, L|N) == TriL(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.LOWER) A0.Copy(A) blasd.UpdateSym(A, Bt, 1.0, 1.0, gomas.LOWER|gomas.TRANSA, conf) blasd.Mult(A0, Bt, Bt, 1.0, 1.0, gomas.TRANSA) cmat.TriL(A0, cmat.NONE) ok = A0.AllClose(A) t.Logf("UpdateSym(A, B, L|T) == TriL(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 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 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 }
// 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 }