func TestDTrmmLowerRight(t *testing.T) { N := 563 K := 171 nofail := true A := cmat.NewMatrix(N, N) B := cmat.NewMatrix(K, N) B0 := cmat.NewMatrix(K, N) C := cmat.NewMatrix(K, N) ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean, cmat.LOWER) B.SetFrom(ones) B0.SetFrom(ones) // B = B*A blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.RIGHT) blasd.Mult(C, B0, A, 1.0, 0.0, gomas.NONE) ok := C.AllClose(B) nofail = nofail && ok t.Logf("trmm(B, A, R|L|N) == gemm(C, B, TriL(A)) : %v\n", ok) B.SetFrom(ones) // B = B*A.T blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.RIGHT|gomas.TRANSA) blasd.Mult(C, B0, A, 1.0, 0.0, gomas.TRANSB) ok = C.AllClose(B) nofail = nofail && ok t.Logf("trmm(B, A, R|L|T) == gemm(C, B, TriL(A).T) : %v\n", ok) }
func TestDTrmmLower(t *testing.T) { N := 563 K := 171 nofail := true A := cmat.NewMatrix(N, N) B := cmat.NewMatrix(N, K) B0 := cmat.NewMatrix(N, K) C := cmat.NewMatrix(N, K) ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean, cmat.LOWER) B.SetFrom(ones) B0.SetFrom(ones) // B = A*B blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.LEFT) blasd.Mult(C, A, B0, 1.0, 0.0, gomas.NONE) ok := C.AllClose(B) nofail = nofail && ok t.Logf("trmm(B, A, L|L|N) == gemm(C, TriL(A), B) : %v\n", ok) B.SetFrom(ones) // B = A.T*B blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.LEFT|gomas.TRANSA) blasd.Mult(C, A, B0, 1.0, 0.0, gomas.TRANSA) ok = C.AllClose(B) nofail = nofail && ok t.Logf("trmm(B, A, L|L|T) == gemm(C, TriL(A).T, B) : %v\n", ok) }
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) }
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) }
// compute: // Q.T*C = (I -Y*T*Y.T).T*C == C - Y*(C.T*Y*T).T // or // Q*C = (I -Y*T*Y.T)*C == C - Y*(C.T*Y*T.T).T // // // where C = ( C2 ) Y = ( Y2 Y1 ) // ( C1 ) // // C1 is nb*K, C2 is P*K, Y1 is nb*nb triuu, Y2 is nb*P, T is nb*nb // W = K*nb func updateLeftRQ(C1, C2, Y1t, Y2t, T, W *cmat.FloatMatrix, transpose bool, conf *gomas.Config) { // W = C1.T blasd.Plus(W, C1, 0.0, 1.0, gomas.TRANSB) // W = C1.T*Y1.T blasd.MultTrm(W, Y1t, 1.0, gomas.RIGHT|gomas.LOWER|gomas.UNIT|gomas.TRANSA, conf) // W = W + C2.T*Y2.T blasd.Mult(W, C2, Y2t, 1.0, 1.0, gomas.TRANSA|gomas.TRANSB, conf) // --- here: W == C.T*Y == C1.T*Y1.T + C2.T*Y2.T --- tflags := gomas.RIGHT | gomas.LOWER if !transpose { tflags |= gomas.TRANSA } // W = W*T or W*T.T blasd.MultTrm(W, T, 1.0, tflags, conf) // --- here: W == C.T*Y*T or C.T*Y*T.T --- // C2 = C2 - Y2*W.T blasd.Mult(C2, Y2t, W, -1.0, 1.0, gomas.TRANSA|gomas.TRANSB, conf) // W = Y1*W.T ==> W.T = W*Y1 blasd.MultTrm(W, Y1t, 1.0, gomas.RIGHT|gomas.LOWER|gomas.UNIT, conf) // C1 = C1 - W.T blasd.Plus(C1, W, 1.0, -1.0, gomas.TRANSB) // --- here: C = (I - Y*T*Y.T).T * C --- }
// compute: // C*Q.T = C*(I -Y*T*Y.T).T == C - C*Y*T.T*Y.T // or // C*Q = (I -Y*T*Y.T)*C == C - C*Y*T*Y.T // // // where C = ( C2 C1 ), Y = ( Y2 Y1 ) // // C1 is K*nb, C2 is K*P, Y1 is nb*nb triuu, Y2 is nb*P, T is nb*nb // W = K*nb func updateRightRQ(C1, C2, Y1t, Y2t, T, W *cmat.FloatMatrix, transpose bool, conf *gomas.Config) { // -- compute: W = C*Y = C1*Y1 + C2*Y2 // W = C1 blasd.Plus(W, C1, 0.0, 1.0, gomas.NONE) // W = C1*Y1t.T blasd.MultTrm(W, Y1t, 1.0, gomas.RIGHT|gomas.LOWER|gomas.UNIT|gomas.TRANSA, conf) // W = W + C2*Y2t.T blasd.Mult(W, C2, Y2t, 1.0, 1.0, gomas.TRANSB, conf) // --- here: W == C*Y --- tflags := gomas.RIGHT | gomas.LOWER if transpose { tflags |= gomas.TRANSA } // W = W*T or W*T.T blasd.MultTrm(W, T, 1.0, tflags, conf) // --- here: W == C*Y*T or C*Y*T.T --- // C2 = C2 - W*Y2t blasd.Mult(C2, W, Y2t, -1.0, 1.0, gomas.NONE, conf) // C1 = C1 - W*Y1t // W = W*Y1 blasd.MultTrm(W, Y1t, 1.0, gomas.RIGHT|gomas.LOWER|gomas.UNIT, conf) // C1 = C1 - W blasd.Plus(C1, W, 1.0, -1.0, gomas.NONE) // --- here: C = (I - Y*T*Y.T).T * C --- }
func TestDTrsm1(t *testing.T) { nofail := true const N = 31 const K = 4 A := cmat.NewMatrix(N, N) B := cmat.NewMatrix(N, K) B0 := cmat.NewMatrix(N, K) ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatUniformSource(1.0, -0.5) A.SetFrom(zeromean, cmat.LOWER) B.SetFrom(ones) B0.Copy(B) // B = A*B blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.LEFT) blasd.SolveTrm(B, A, 1.0, gomas.LOWER|gomas.LEFT) ok := B0.AllClose(B) nofail = nofail && ok t.Logf("B == trsm(trmm(B, A, L|L|N), A, L|L|N) : %v\n", ok) if !ok { t.Logf("B|B0:\n%v\n", cmat.NewJoin(cmat.AUGMENT, B, B0)) } B.Copy(B0) // B = A.T*B blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.LEFT|gomas.TRANSA) blasd.SolveTrm(B, A, 1.0, gomas.LOWER|gomas.LEFT|gomas.TRANSA) ok = B0.AllClose(B) nofail = nofail && ok t.Logf("B == trsm(trmm(B, A, L|L|T), A, L|L|T) : %v\n", ok) }
func TestDTrsm3(t *testing.T) { const N = 31 const K = 4 A := cmat.NewMatrix(N, N) B := cmat.NewMatrix(N, K) B0 := cmat.NewMatrix(N, K) ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatUniformSource(1.0, -0.5) A.SetFrom(zeromean, cmat.UPPER) B.SetFrom(ones) B0.Copy(B) // B = A*B blasd.MultTrm(B, A, 1.0, gomas.UPPER|gomas.LEFT) blasd.SolveTrm(B, A, 1.0, gomas.UPPER|gomas.LEFT) ok := B0.AllClose(B) t.Logf("B == trsm(trmm(B, A, L|U|N), A, L|U|N) : %v\n", ok) B.Copy(B0) // B = A.T*B blasd.MultTrm(B, A, 1.0, gomas.UPPER|gomas.LEFT|gomas.TRANSA) blasd.SolveTrm(B, A, 1.0, gomas.UPPER|gomas.LEFT|gomas.TRANSA) ok = B0.AllClose(B) t.Logf("B == trsm(trmm(B, A, L|U|T), A, L|U|T) : %v\n", ok) }
func TestDTrms2(t *testing.T) { const N = 31 const K = 4 nofail := true A := cmat.NewMatrix(N, N) B := cmat.NewMatrix(K, N) B0 := cmat.NewMatrix(K, N) ones := cmat.NewFloatConstSource(1.0) zeromean := cmat.NewFloatUniformSource(1.0, -0.5) A.SetFrom(zeromean, cmat.LOWER) B.SetFrom(ones) B0.Copy(B) // B = B*A blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.RIGHT) blasd.SolveTrm(B, A, 1.0, gomas.LOWER|gomas.RIGHT) ok := B0.AllClose(B) nofail = nofail && ok t.Logf("B == trsm(trmm(B, A, R|L|N), A, R|L|N) : %v\n", ok) B.Copy(B0) // B = B*A.T blasd.MultTrm(B, A, 1.0, gomas.LOWER|gomas.RIGHT|gomas.TRANSA) blasd.SolveTrm(B, A, 1.0, gomas.LOWER|gomas.RIGHT|gomas.TRANSA) ok = B0.AllClose(B) nofail = nofail && ok t.Logf("B == trsm(trmm(B, A, R|L|T), A, R|L|T) : %v\n", ok) }
// update T: T = -T1*Y1.T*Y2*T2 // Y1 = /Y10\ Y2 = /Y11\ // \Y20/ \Y21/ // // T = -T1 * [Y10.T*Y11 + Y20.T*Y21]*T2 // // T1 is K*K triangular upper matrix // T2 is nb*nb triangular upper matrix // T is K*nb block matrix // Y10 is nb*K block matrix // Y20 is M-K-nb*K block matrix // Y11 is nb*nb triangular lower unit diagonal matrix // Y21 is M-K-nb*nb block matrix // func updateQRTReflector(T, Y10, Y20, Y11, Y21, T1, T2 *cmat.FloatMatrix, conf *gomas.Config) { // T = Y10.T if n(Y10) == 0 { return } // T = Y10.T blasd.Plus(T, Y10, 0.0, 1.0, gomas.TRANSB) // T = Y10.T*Y11 blasd.MultTrm(T, Y11, 1.0, gomas.LOWER|gomas.UNIT|gomas.RIGHT, conf) // T = T + Y20.T*Y21 blasd.Mult(T, Y20, Y21, 1.0, 1.0, gomas.TRANSA, conf) // -- here: T == Y1.T*Y2 // T = -T1*T blasd.MultTrm(T, T1, -1.0, gomas.UPPER, conf) // T = T*T2 blasd.MultTrm(T, T2, 1.0, gomas.UPPER|gomas.RIGHT, conf) }
/* * 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 }