/* * like LAPACK/dlafrt.f * * Build block reflector T from HH reflector stored in TriLU(A) and coefficients * in tau. * * Q = I - Y*T*Y.T; Householder H = I - tau*v*v.T * * T = | T 0 | z = -tau*T*Y.T*v * | z c | c = tau * * Q = H(1)H(2)...H(k) building forward here. */ func unblkBlockReflectorRQ(T, A, tau *cmat.FloatMatrix) { var ATL, ABR cmat.FloatMatrix var A00, a10, A20, a11, a21, A22 cmat.FloatMatrix var TTL, TBR cmat.FloatMatrix var T00, t11, t21, T22 cmat.FloatMatrix var tT, tB cmat.FloatMatrix var t0, tau1, t2 cmat.FloatMatrix util.Partition2x2( &ATL, nil, nil, &ABR /**/, A, 0, 0, util.PBOTTOMRIGHT) util.Partition2x2( &TTL, nil, nil, &TBR /**/, T, 0, 0, util.PBOTTOMRIGHT) util.Partition2x1( &tT, &tB /**/, tau, 0, util.PBOTTOM) for m(&ATL) > 0 && n(&ATL) > 0 { util.Repartition2x2to3x3(&ATL, &A00, nil, nil, &a10, &a11, nil, &A20, &a21, &A22 /**/, A, 1, util.PTOPLEFT) util.Repartition2x2to3x3(&TTL, &T00, nil, nil, nil, &t11, nil, nil, &t21, &T22 /**/, T, 1, util.PTOPLEFT) util.Repartition2x1to3x1(&tT, &t0, &tau1, &t2 /**/, tau, 1, util.PTOP) // -------------------------------------------------- // t11 := tau tauval := tau1.Get(0, 0) if tauval != 0.0 { t11.Set(0, 0, tauval) // t21 := -tauval*(a21 + A20*a10) blasd.Axpby(&t21, &a21, 1.0, 0.0) blasd.MVMult(&t21, &A20, &a10, -tauval, -tauval, gomas.NONE) // t21 := T22*t21 blasd.MVMultTrm(&t21, &T22, 1.0, gomas.LOWER) } // -------------------------------------------------- util.Continue3x3to2x2( &ATL, nil, nil, &ABR /**/, &A00, &a11, &A22, A, util.PTOPLEFT) util.Continue3x3to2x2( &TTL, nil, nil, &TBR /**/, &T00, &t11, &T22, T, util.PTOPLEFT) util.Continue3x1to2x1( &tT, &tB /**/, &t0, &tau1, tau, util.PTOP) } }
/* * like LAPACK/dlafrt.f * * Build block reflector T from HH reflector stored in TriLU(A) and coefficients * in tau. * * Q = I - Y*T*Y.T; Householder H = I - tau*v*v.T * * T = | T z | z = -tau*T*Y.T*v * | 0 c | c = tau * * Q = H(1)H(2)...H(k) building forward here. */ func unblkQLBlockReflector(T, A, tau *cmat.FloatMatrix) { var ATL, ABR cmat.FloatMatrix var A00, a01, a11, A02, a12, A22 cmat.FloatMatrix var TTL, TBR cmat.FloatMatrix var T00, t11, t21, T22 cmat.FloatMatrix var tT, tB cmat.FloatMatrix var t0, tau1, t2 cmat.FloatMatrix util.Partition2x2( &ATL, nil, nil, &ABR, A, 0, 0, util.PBOTTOMRIGHT) util.Partition2x2( &TTL, nil, nil, &TBR, T, 0, 0, util.PBOTTOMRIGHT) util.Partition2x1( &tT, &tB, tau, 0, util.PBOTTOM) for m(&ATL) > 0 && n(&ATL) > 0 { util.Repartition2x2to3x3(&ATL, &A00, &a01, &A02, nil, &a11, &a12, nil, nil, &A22, A, 1, util.PTOPLEFT) util.Repartition2x2to3x3(&TTL, &T00, nil, nil, nil, &t11, nil, nil, &t21, &T22, T, 1, util.PTOPLEFT) util.Repartition2x1to3x1(&tT, &t0, &tau1, &t2, tau, 1, util.PTOP) // -------------------------------------------------- // t11 := tau tauval := tau1.Get(0, 0) if tauval != 0.0 { t11.Set(0, 0, tauval) // t21 := -tauval*(a12.T + &A02.T*a12) blasd.Axpby(&t21, &a12, 1.0, 0.0) blasd.MVMult(&t21, &A02, &a01, -tauval, -tauval, gomas.TRANSA) // t21 := T22*t01 blasd.MVMultTrm(&t21, &T22, 1.0, gomas.LOWER) } // -------------------------------------------------- util.Continue3x3to2x2( &ATL, nil, nil, &ABR, &A00, &a11, &A22, A, util.PTOPLEFT) util.Continue3x3to2x2( &TTL, nil, nil, &TBR, &T00, &t11, &T22, T, util.PTOPLEFT) util.Continue3x1to2x1( &tT, &tB, &t0, &tau1, tau, util.PTOP) } }
/* * like LAPACK/dlafrt.f * * Build block reflector T from HH reflector stored in TriLU(A) and coefficients * in tau. * * Q = I - Y*T*Y.T; Householder H = I - tau*v*v.T * * T = | T z | z = -tau*T*Y.T*v * | 0 c | c = tau * * Q = H(1)H(2)...H(k) building forward here. */ func unblkBlockReflectorLQ(T, A, tau *cmat.FloatMatrix) { var ATL, ATR, ABL, ABR cmat.FloatMatrix var A00, a01, A02, a11, a12, A22 cmat.FloatMatrix var TTL, TTR, TBL, TBR cmat.FloatMatrix var T00, t01, T02, t11, t12, T22 cmat.FloatMatrix var tT, tB cmat.FloatMatrix var t0, tau1, t2 cmat.FloatMatrix util.Partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, util.PTOPLEFT) util.Partition2x2( &TTL, &TTR, &TBL, &TBR, T, 0, 0, util.PTOPLEFT) util.Partition2x1( &tT, &tB, tau, 0, util.PTOP) for m(&ABR) > 0 && n(&ABR) > 0 { util.Repartition2x2to3x3(&ATL, &A00, &a01, &A02, nil, &a11, &a12, nil, nil, &A22, A, 1, util.PBOTTOMRIGHT) util.Repartition2x2to3x3(&TTL, &T00, &t01, &T02, nil, &t11, &t12, nil, nil, &T22, T, 1, util.PBOTTOMRIGHT) util.Repartition2x1to3x1(&tT, &t0, &tau1, &t2, tau, 1, util.PBOTTOM) // -------------------------------------------------- // t11 := tau tauval := tau1.Get(0, 0) if tauval != 0.0 { t11.Set(0, 0, tauval) // t01 := -tauval*(a01 + A02*a12) blasd.Axpby(&t01, &a01, 1.0, 0.0) blasd.MVMult(&t01, &A02, &a12, -tauval, -tauval, gomas.NONE) // t01 := T00*t01 blasd.MVMultTrm(&t01, &T00, 1.0, gomas.UPPER) } // -------------------------------------------------- util.Continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, util.PBOTTOMRIGHT) util.Continue3x3to2x2( &TTL, &TTR, &TBL, &TBR, &T00, &t11, &T22, T, util.PBOTTOMRIGHT) util.Continue3x1to2x1( &tT, &tB, &t0, &tau1, tau, util.PBOTTOM) } }
/* * Unblocked QR decomposition with block reflector T. */ func unblockedQRT(A, T, W *cmat.FloatMatrix) *gomas.Error { var err *gomas.Error = nil var ATL, ATR, ABL, ABR cmat.FloatMatrix var A00, a10, a11, a12, A20, a21, A22 cmat.FloatMatrix var TTL, TTR, TBL, TBR cmat.FloatMatrix var T00, t01, T02, t11, t12, T22, w12 cmat.FloatMatrix util.Partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, util.PTOPLEFT) util.Partition2x2( &TTL, &TTR, &TBL, &TBR, T, 0, 0, util.PTOPLEFT) for m(&ABR) > 0 && n(&ABR) > 0 { util.Repartition2x2to3x3(&ATL, &A00, nil, nil, &a10, &a11, &a12, &A20, &a21, &A22, A, 1, util.PBOTTOMRIGHT) util.Repartition2x2to3x3(&TTL, &T00, &t01, &T02, nil, &t11, &t12, nil, nil, &T22, T, 1, util.PBOTTOMRIGHT) // ------------------------------------------------------ computeHouseholder(&a11, &a21, &t11) // H*[a12 A22].T w12.SubMatrix(W, 0, 0, a12.Len(), 1) applyHouseholder2x1(&t11, &a21, &a12, &A22, &w12, gomas.LEFT) // update T tauval := t11.Get(0, 0) if tauval != 0.0 { // t01 := -tauval*(a10.T + &A20.T*a21) //a10.CopyTo(&t01) blasd.Axpby(&t01, &a10, 1.0, 0.0) blasd.MVMult(&t01, &A20, &a21, -tauval, -tauval, gomas.TRANSA) // t01 := T00*t01 blasd.MVMultTrm(&t01, &T00, 1.0, gomas.UPPER) } // ------------------------------------------------------ util.Continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, util.PBOTTOMRIGHT) util.Continue3x3to2x2( &TTL, &TTR, &TBL, &TBR, &T00, &t11, &T22, T, util.PBOTTOMRIGHT) } return err }
/* * Update vector with compact WY Householder block * (I - Y*T*Y.T)*v = v - Y*T*Y.T*v * * LEFT: * 1 | 0 * v0 = v0 = v0 * 0 | Q v1 Q*v1 = v1 - Y*T*Y.T*v1 * * 1 | 0 * v0 = v0 = v0 * 0 | Q.T v1 Q.T*v1 = v1 - Y*T.T*Y.T*v1 * * RIGHT: * v0 | v1 * 1 | 0 = v0 | v1*Q = v0 | v1 - v1*Y*T*Y.T * 0 | Q * * v0 | v1 * 1 | 0 = v0 | v1*Q.T = v0 | v1 - v1*Y*T.T*Y.T * 0 | Q.T */ func updateVecLeftWY2(v, Y1, Y2, T, w *cmat.FloatMatrix, bits int) { var v1, v2 cmat.FloatMatrix var w0 cmat.FloatMatrix v1.SubMatrix(v, 1, 0, n(Y1), 1) v2.SubMatrix(v, n(Y1)+1, 0, m(Y2), 1) w0.SubMatrix(w, 0, 0, m(Y1), 1) // w0 := Y1.T*v1 + Y2.T*v2 blasd.Copy(&w0, &v1) blasd.MVMultTrm(&w0, Y1, 1.0, gomas.LOWER|gomas.UNIT|gomas.TRANS) blasd.MVMult(&w0, Y2, &v2, 1.0, 1.0, gomas.TRANS) // w0 := op(T)*w0 blasd.MVMultTrm(&w0, T, 1.0, bits|gomas.UPPER) // v2 := v2 - Y2*w0 blasd.MVMult(&v2, Y2, &w0, -1.0, 1.0, gomas.NONE) // v1 := v1 - Y1*w0 blasd.MVMultTrm(&w0, Y1, 1.0, gomas.LOWER|gomas.UNIT) blasd.Axpy(&v1, &w0, -1.0) }
/* * * Building reduction block for blocked algorithm as described in (1). * * A. update next column * a10 [(U00) (U00) ] [(a10) (V00) ] * a11 := I -[(u10)*T00*(u10).T] * [(a11) - (v01) * T00 * a10] * a12 [(U20) (U20) ] [(a12) (V02) ] * * B. compute Householder reflector for updated column * a21, t11 := Householder(a21) * * C. update intermediate reductions * v10 A02*a21 * v11 := a12*a21 * v12 A22*a21 * * D. update block reflector * t01 := A20*a21 * t11 := t11 */ func unblkBuildHessGQvdG(A, T, V, W *cmat.FloatMatrix) *gomas.Error { var ATL, ATR, ABL, ABR cmat.FloatMatrix var A00, a10, a11, A20, a21, A22 cmat.FloatMatrix var AL, AR, A0, a1, A2 cmat.FloatMatrix var TTL, TTR, TBL, TBR cmat.FloatMatrix var T00, t01, t11, T22 cmat.FloatMatrix var VL, VR, V0, v1, V2, Y0 cmat.FloatMatrix util.Partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, util.PTOPLEFT) util.Partition2x2( &TTL, &TTR, &TBL, &TBR, T, 0, 0, util.PTOPLEFT) util.Partition1x2( &AL, &AR, A, 0, util.PLEFT) util.Partition1x2( &VL, &VR, V, 0, util.PLEFT) var beta float64 for n(&VR) > 0 { util.Repartition2x2to3x3(&ATL, &A00, nil, nil, &a10, &a11, nil, &A20, &a21, &A22, A, 1, util.PBOTTOMRIGHT) util.Repartition2x2to3x3(&TTL, &T00, &t01, nil, nil, &t11, nil, nil, nil, &T22, T, 1, util.PBOTTOMRIGHT) util.Repartition1x2to1x3(&AL, &A0, &a1, &A2, A, 1, util.PRIGHT) util.Repartition1x2to1x3(&VL, &V0, &v1, &V2, V, 1, util.PRIGHT) // ------------------------------------------------------ // Compute Hessenberg update for next column of A: if n(&V0) > 0 { // y10 := T00*a10 (use t01 as workspace?) blasd.Axpby(&t01, &a10, 1.0, 0.0) blasd.MVMultTrm(&t01, &T00, 1.0, gomas.UPPER) // a1 := a1 - V0*T00*a10 blasd.MVMult(&a1, &V0, &t01, -1.0, 1.0, gomas.NONE) // update a1 := (I - Y*T*Y.T).T*a1 (here t01 as workspace) Y0.SubMatrix(A, 1, 0, n(&A00), n(&A00)) updateVecLeftWY2(&a1, &Y0, &A20, &T00, &t01, gomas.TRANS) a10.Set(0, -1, beta) } // Compute Householder reflector computeHouseholderVec(&a21, &t11) beta = a21.Get(0, 0) a21.Set(0, 0, 1.0) // v1 := A2*a21 blasd.MVMult(&v1, &A2, &a21, 1.0, 0.0, gomas.NONE) // update T tauval := t11.Get(0, 0) if tauval != 0.0 { // t01 := -tauval*A20.T*a21 blasd.MVMult(&t01, &A20, &a21, -tauval, 0.0, gomas.TRANS) // t01 := T00*t01 blasd.MVMultTrm(&t01, &T00, 1.0, gomas.UPPER) } // ------------------------------------------------------ util.Continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, util.PBOTTOMRIGHT) util.Continue3x3to2x2( &TTL, &TTR, &TBL, &TBR, &T00, &t11, &T22, T, util.PBOTTOMRIGHT) util.Continue1x3to1x2( &AL, &AR, &A0, &a1, A, util.PRIGHT) util.Continue1x3to1x2( &VL, &VR, &V0, &v1, V, util.PRIGHT) } A.Set(n(V), n(V)-1, beta) return nil }