// 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 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) }
func TestBidiagReduceUnblocked(t *testing.T) { N := 217 M := 269 conf := gomas.NewConf() conf.LB = 0 zeromean := cmat.NewFloatNormSource() A := cmat.NewMatrix(M, N) A.SetFrom(zeromean) tauq := cmat.NewMatrix(N, 1) taup := cmat.NewMatrix(N, 1) At := cmat.NewMatrix(N, M) blasd.Transpose(At, A) tauqt := cmat.NewMatrix(N, 1) taupt := cmat.NewMatrix(N, 1) W := lapackd.Workspace(M + N) lapackd.BDReduce(A, tauq, taup, W, conf) lapackd.BDReduce(At, tauqt, taupt, W, conf) // BiRed(A) == BiRed(A.T).T blasd.Plus(At, A, 1.0, -1.0, gomas.TRANSB) blasd.Axpy(tauqt, taup, -1.0) blasd.Axpy(taupt, tauq, -1.0) nrm := lapackd.NormP(At, lapackd.NORM_ONE) t.Logf("M=%d, N=%d || BiRed(A) - BiRed(A.T).T||_1 : %e\n", M, N, nrm) nrm = lapackd.NormP(taupt, lapackd.NORM_ONE) t.Logf(" || BiRed(A).tauq - BiRed(A.T).taup||_1 : %e\n", nrm) nrm = lapackd.NormP(tauqt, lapackd.NORM_ONE) t.Logf(" || BiRed(A).taup - BiRed(A.T).tauq||_1 : %e\n", nrm) }
// test: unblk.ReduceHess(A) == blk.ReduceHess(A) func TestReduceHess(t *testing.T) { N := 375 nb := 16 conf := gomas.NewConf() conf.LB = nb A := cmat.NewMatrix(N, N) tau := cmat.NewMatrix(N, 1) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean) A0 := cmat.NewCopy(A) tau0 := cmat.NewCopy(tau) // blocked reduction W := lapackd.Workspace(lapackd.HessReduceWork(A, conf)) lapackd.HessReduce(A, tau, W, conf) // unblocked reduction conf.LB = 0 lapackd.HessReduce(A0, tau0, W, conf) ok := A.AllClose(A0) t.Logf("blk.ReduceHess(A) == unblk.ReduceHess(A): %v\n", ok) ok = tau0.AllClose(tau) t.Logf("blk HessQ.tau == unblk HessQ.tau: %v\n", ok) // ||A - A0||_1 blasd.Plus(A, A0, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(A, lapackd.NORM_ONE) t.Logf("||H - H0||_1: %e\n", nrm) }
// test: min || B - A.T*X || func TestLeastSquaresLQ(t *testing.T) { M := 723 N := 811 K := 273 nb := 32 conf := gomas.NewConf() conf.LB = nb tau := cmat.NewMatrix(M, 1) A := cmat.NewMatrix(M, N) src := cmat.NewFloatNormSource() A.SetFrom(src) B0 := cmat.NewMatrix(M, K) B0.SetFrom(src) B := cmat.NewMatrix(N, K) // B = A.T*B0 blasd.Mult(B, A, B0, 1.0, 0.0, gomas.TRANSA, conf) W := lapackd.Workspace(lapackd.LQFactorWork(A, conf)) lapackd.LQFactor(A, tau, W, conf) // B' = A.-1*B lapackd.LQSolve(B, A, tau, W, gomas.TRANS, conf) // expect B[0:M,0:K] == B0[0:M,0:K], B[M:N,0:K] == 0 var X cmat.FloatMatrix X.SubMatrix(B, 0, 0, M, K) blasd.Plus(&X, B0, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(&X, lapackd.NORM_ONE) t.Logf("M=%d, N=%d ||B0 - min( ||A.T*X - B0|| ) ||_1: %e\n", M, N, nrm) }
func TestLQFactor(t *testing.T) { M := 611 N := 715 nb := 32 conf := gomas.NewConf() A := cmat.NewMatrix(M, N) src := cmat.NewFloatNormSource() A.SetFrom(src) tau := cmat.NewMatrix(M, 1) A1 := cmat.NewCopy(A) tau1 := cmat.NewCopy(tau) conf.LB = 0 W := cmat.NewMatrix(M+N, 1) lapackd.LQFactor(A, tau, W, conf) conf.LB = nb W1 := lapackd.Workspace(lapackd.LQFactorWork(A1, conf)) lapackd.LQFactor(A1, tau1, W1, conf) blasd.Plus(A1, A, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(A1, lapackd.NORM_ONE) t.Logf("M=%d, N=%d ||blk.LQ(A) - unblk.LQ(A)||_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) }
// m > n: A[m,n], I[m,m] --> A == I*A == Q*Q.T*A func TestQRTMultLeftIdent(t *testing.T) { M := 411 N := 399 nb := 16 A := cmat.NewMatrix(M, N) T := cmat.NewMatrix(nb, N) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean) A0 := cmat.NewCopy(A) C := 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 = Q.T*A W = lapackd.Workspace(lapackd.QRTMultWork(C, T, gomas.LEFT, conf)) lapackd.QRTMult(C, A, T, W, gomas.LEFT|gomas.TRANS, conf) // C = Q*C == Q*Q.T*A lapackd.QRTMult(C, A, T, W, gomas.LEFT, conf) //t.Logf("A*Q*Q.T:\n%v\n", C) // A = A - Q*Q.T*A blasd.Plus(A0, C, 1.0, -1.0, gomas.NONE) // ||A - Q*Q.T*A||_1 nrm := lapackd.NormP(A0, lapackd.NORM_ONE) t.Logf("M=%d,N=%d ||A - Q*Q.T*A||_1: %e\n", M, N, nrm) }
// 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) }
// m > n: A[m,n], I[m,m] --> A.T == A.T*I == A.T*Q*Q.T func TestBlockedQRMultRightIdent(t *testing.T) { M := 511 N := 489 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) C.Transpose(A) conf := gomas.NewConf() conf.LB = 32 // QR = A = Q*R W := lapackd.Workspace(lapackd.QRFactorWork(A, conf)) lapackd.QRFactor(A, tau, W, conf) // C = A.T*Q W = lapackd.Workspace(lapackd.QRMultWork(C, gomas.RIGHT, conf)) lapackd.QRMult(C, A, tau, W, gomas.RIGHT, conf) // C = C*Q.T == A.T*Q*Q.T lapackd.QRMult(C, A, tau, W, gomas.RIGHT|gomas.TRANS, conf) //t.Logf("A*Q*Q.T:\n%v\n", C) // A = A - (A.T*Q*Q.T).T blasd.Plus(A0, C, 1.0, -1.0, gomas.TRANSB) // ||A - (A.T*Q*Q.T).T||_1 nrm := lapackd.NormP(A0, lapackd.NORM_ONE) t.Logf("M=%d,N=%d ||A - (A.T*Q*Q.T).T||_1: %e\n", M, N, nrm) }
// 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) }
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) }
func TestSolveBKLowerBig(t *testing.T) { N := 427 normsrc := cmat.NewFloatNormSource(5.0, 10.0) A := cmat.NewMatrix(N, N) A.SetFrom(normsrc, cmat.LOWER) X := cmat.NewMatrix(N, 2) X.SetFrom(normsrc) B := cmat.NewCopy(X) blasd.MultSym(B, A, X, 1.0, 0.0, gomas.LOWER|gomas.LEFT) ipiv := lapackd.NewPivots(N) conf := gomas.NewConf() conf.LB = 16 W := lapackd.Workspace(lapackd.BKFactorWork(A, conf)) lapackd.BKFactor(A, W, ipiv, gomas.LOWER, conf) lapackd.BKSolve(B, A, ipiv, gomas.LOWER, conf) ok := B.AllClose(X) t.Logf("N=%d unblk.BK(X) == A.-1*B : %v\n", N, ok) blasd.Plus(B, X, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(B, lapackd.NORM_ONE) t.Logf(" ||X - A.-1*B||_1: %.4e\n", nrm) }
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) }
// test: A - Q*Hess(A)*Q.T == 0 func TestMultHess(t *testing.T) { N := 377 nb := 16 conf := gomas.NewConf() conf.LB = nb A := cmat.NewMatrix(N, N) tau := cmat.NewMatrix(N, 1) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean) A0 := cmat.NewCopy(A) // reduction W := lapackd.Workspace(lapackd.HessReduceWork(A, conf)) lapackd.HessReduce(A, tau, W, conf) var Hlow cmat.FloatMatrix H := cmat.NewCopy(A) // set triangular part below first subdiagonal to zeros zeros := cmat.NewFloatConstSource(0.0) Hlow.SubMatrix(H, 1, 0, N-1, N-1) Hlow.SetFrom(zeros, cmat.LOWER|cmat.UNIT) H1 := cmat.NewCopy(H) // H := Q*H*Q.T conf.LB = nb lapackd.HessMult(H, A, tau, W, gomas.LEFT, conf) lapackd.HessMult(H, A, tau, W, gomas.RIGHT|gomas.TRANS, conf) // H := Q*H*Q.T conf.LB = 0 lapackd.HessMult(H1, A, tau, W, gomas.LEFT, conf) lapackd.HessMult(H1, A, tau, W, gomas.RIGHT|gomas.TRANS, conf) // compute ||Q*Hess(A)*Q.T - A||_1 blasd.Plus(H, A0, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(H, lapackd.NORM_ONE) t.Logf(" blk.|| Q*Hess(A)*Q.T - A ||_1 : %e\n", nrm) blasd.Plus(H1, A0, 1.0, -1.0, gomas.NONE) nrm = lapackd.NormP(H1, lapackd.NORM_ONE) t.Logf("unblk.|| Q*Hess(A)*Q.T - A ||_1 : %e\n", nrm) }
// 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) }
// test: ||A - A*Q*Q.T||_1 ~= 0 func TestLQMultRight(t *testing.T) { M := 511 N := 627 nb := 24 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) A0 := cmat.NewCopy(A) A1 := cmat.NewCopy(A) A2 := cmat.NewCopy(A) conf.LB = 0 lapackd.LQFactor(A, tau, W, conf) // unblocked A1 := A1*Q*Q.T conf.LB = 0 lapackd.LQMult(A1, A, tau, W, gomas.RIGHT, conf) lapackd.LQMult(A1, A, tau, W, gomas.RIGHT|gomas.TRANS, conf) // blocked A2 := A2*Q*Q.T conf.LB = nb W = lapackd.Workspace(lapackd.LQMultWork(A2, gomas.RIGHT, conf)) lapackd.LQMult(A2, A, tau, W, gomas.RIGHT, conf) lapackd.LQMult(A2, A, tau, W, gomas.RIGHT|gomas.TRANS, conf) // A1 - A0 == 0 blasd.Plus(A1, A0, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(A1, lapackd.NORM_ONE) t.Logf("M=%d, N=%d, unblk.||A - A*Q*Q.T||_1: %e\n", M, N, nrm) // A2 - A0 == 0 blasd.Plus(A2, A0, 1.0, -1.0, gomas.NONE) nrm = lapackd.NormP(A2, lapackd.NORM_ONE) t.Logf("M=%d, N=%d, nb=%d blk.||A - A*Q*Q.T||_1: %e\n", M, N, nb, nrm) }
// test: ||C - Q*Q.T*C||_1 ~= 0; // multipling from left requires: m(C) == n(A) [n(Q)] func TestLQMultLeft(t *testing.T) { M := 771 N := 813 nb := 16 conf := gomas.NewConf() A := cmat.NewMatrix(M, N) src := cmat.NewFloatNormSource() A.SetFrom(src) // C0 := A C0 := cmat.NewCopy(A) C1t := cmat.NewMatrix(N, M) blasd.Transpose(C1t, C0) C2t := cmat.NewCopy(C1t) tau := cmat.NewMatrix(M, 1) W := cmat.NewMatrix(M+N, 1) conf.LB = 0 lapackd.LQFactor(A, tau, W, conf) // A0 := Q.T*A0 conf.LB = 0 lapackd.LQMult(C2t, A, tau, W, gomas.LEFT, conf) lapackd.LQMult(C2t, A, tau, W, gomas.LEFT|gomas.TRANS, conf) // A0 := Q.T*A0 conf.LB = nb W1 := lapackd.Workspace(lapackd.LQMultWork(C1t, gomas.LEFT, conf)) lapackd.LQMult(C1t, A, tau, W1, gomas.LEFT, conf) lapackd.LQMult(C1t, A, tau, W1, gomas.LEFT|gomas.TRANS, conf) blasd.Plus(C0, C1t, 1.0, -1.0, gomas.TRANSB) nrm := lapackd.NormP(C0, lapackd.NORM_ONE) t.Logf("M=%d, N=%d, ||C - Q*Q*T*C||_1: %e\n", M, N, nrm) blasd.Plus(C1t, C2t, 1.0, -1.0, gomas.NONE) nrm = lapackd.NormP(C1t, lapackd.NORM_ONE) t.Logf("M=%d, N=%d, ||unblk(Q*Q.T*C) - blk(Q*Q*T*C)||_1: %e\n", M, N, nrm) }
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) }
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) }
// 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) }
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) }
// 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) }
// test: min || B - A*X || func TestLeastSquaresQR(t *testing.T) { M := 811 N := 723 K := 311 nb := 32 conf := gomas.NewConf() conf.LB = nb tau := cmat.NewMatrix(N, 1) A := cmat.NewMatrix(M, N) src := cmat.NewFloatNormSource() A.SetFrom(src) B0 := cmat.NewMatrix(N, K) B0.SetFrom(src) B := cmat.NewMatrix(M, K) // B = A*B0 blasd.Mult(B, A, B0, 1.0, 0.0, gomas.NONE, conf) W := lapackd.Workspace(lapackd.QRFactorWork(A, conf)) err := lapackd.QRFactor(A, tau, W, conf) if err != nil { t.Logf("DecomposeQR: %v\n", err) } // B' = A.-1*B err = lapackd.QRSolve(B, A, tau, W, gomas.NONE, conf) if err != nil { t.Logf("SolveQR: %v\n", err) } // expect B[0:N,0:K] == B0[0:N,0:K], B[N:M,0:K] == 0 var X cmat.FloatMatrix X.SubMatrix(B, 0, 0, N, K) blasd.Plus(&X, B0, 1.0, -1.0, gomas.NONE) nrm := lapackd.NormP(&X, lapackd.NORM_ONE) t.Logf("M=%d, N=%d ||B0 - min( ||A*X - B0|| ) ||_1: %e\n", M, N, nrm) }
// m > n: A[m,n], I[m,m] --> A.T == A.T*I == A.T*Q*Q.T func TestQRTMultRightIdent(t *testing.T) { M := 511 N := 399 nb := 16 A := cmat.NewMatrix(M, N) C := cmat.NewMatrix(N, M) T := cmat.NewMatrix(nb, N) zeromean := cmat.NewFloatNormSource() A.SetFrom(zeromean) A0 := cmat.NewCopy(A) C.Transpose(A) conf := gomas.NewConf() conf.LB = nb // QR = A = Q*R W := lapackd.Workspace(lapackd.QRTFactorWork(A, conf)) lapackd.QRTFactor(A, T, W, conf) // C = A*Q W = lapackd.Workspace(lapackd.QRTMultWork(C, T, gomas.RIGHT, conf)) err := lapackd.QRTMult(C, A, T, W, gomas.RIGHT, conf) if err != nil { t.Logf("err: %v\n", err) } // C = C*Q.T == A*Q*Q.T err = lapackd.QRTMult(C, A, T, W, gomas.RIGHT|gomas.TRANS, conf) if err != nil { t.Logf("err: %v\n", err) } // A = A - (A.T*Q*Q.T).T 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 - (A.T*Q*Q.T).T||_1: %e\n", M, N, nrm) }
func TestBidiagReduceBlockedTall(t *testing.T) { N := 711 M := 883 nb := 64 conf := gomas.NewConf() conf.LB = 0 zeromean := cmat.NewFloatNormSource() A := cmat.NewMatrix(M, N) A.SetFrom(zeromean) tauq := cmat.NewMatrix(N, 1) taup := cmat.NewMatrix(N, 1) A1 := cmat.NewCopy(A) tauq1 := cmat.NewMatrix(N, 1) taup1 := cmat.NewMatrix(N, 1) W := lapackd.Workspace(M + N) W1 := lapackd.Workspace(nb * (M + N + 1)) lapackd.BDReduce(A, tauq, taup, W, conf) conf.LB = nb lapackd.BDReduce(A1, tauq1, taup1, W1, conf) // unblk.BiRed(A) == blk.BiRed(A) blasd.Plus(A1, A, 1.0, -1.0, gomas.NONE) blasd.Axpy(tauq1, tauq, -1.0) blasd.Axpy(taup1, taup, -1.0) nrm := lapackd.NormP(A1, lapackd.NORM_ONE) t.Logf("M=%d, N=%d || unblk.BiRed(A) - blk.BiRed(A)||_1 : %e\n", M, N, nrm) nrm = lapackd.NormP(taup1, lapackd.NORM_ONE) t.Logf(" || unblk.BiRed(A).tauq - blk.BiRed(A).taup||_1 : %e\n", nrm) nrm = lapackd.NormP(tauq1, lapackd.NORM_ONE) t.Logf(" || unblk.BiRed(A).taup - blk.BiRed(A).tauq||_1 : %e\n", nrm) }
func TestReduceBidiagBlkWide(t *testing.T) { N := 911 M := 823 nb := 48 conf := gomas.NewConf() conf.LB = 0 zeromean := cmat.NewFloatNormSource() A := cmat.NewMatrix(M, N) A.SetFrom(zeromean) tauq := cmat.NewMatrix(N, 1) taup := cmat.NewMatrix(N, 1) A1 := cmat.NewCopy(A) tauq1 := cmat.NewMatrix(N, 1) taup1 := cmat.NewMatrix(N, 1) W := lapackd.Workspace(M + N) lapackd.BDReduce(A, tauq, taup, W, conf) conf.LB = nb W1 := lapackd.Workspace(lapackd.BDReduceWork(A1, conf)) lapackd.BDReduce(A1, tauq1, taup1, W1, conf) // BiRed(A) == BiRed(A.T).T blasd.Plus(A1, A, 1.0, -1.0, gomas.NONE) blasd.Axpy(tauq1, tauq, -1.0) blasd.Axpy(taup1, taup, -1.0) nrm := lapackd.NormP(A1, lapackd.NORM_ONE) t.Logf("M=%d, N=%d || BiRed(A) - blk.BiRed(A)||_1 : %e\n", M, N, nrm) nrm = lapackd.NormP(taup1, lapackd.NORM_ONE) t.Logf(" || BiRed(A).tauq - blk.BiRed(A).taup||_1 : %e\n", nrm) nrm = lapackd.NormP(tauq1, lapackd.NORM_ONE) t.Logf(" || BiRed(A).taup - blk.BiRed(A).tauq||_1 : %e\n", nrm) }
// 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) }
// 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) }