Esempio n. 1
0
/*
 * Multiply and replace C with product of C and Q or P where Q and P are real orthogonal matrices
 * defined as the product of k elementary reflectors.
 *
 *    Q = H(1) H(2) . . . H(k)   and   P = G(1) G(2). . . G(k)
 *
 * as returned by ReduceBidiag().
 *
 * Arguments:
 *  C     On entry, the M-by-N matrix C or if flag bit RIGHT is set then N-by-M matrix
 *        On exit C is overwritten by Q*C or Q.T*C. If bit RIGHT is set then C is
 *        overwritten by C*Q or C*Q.T
 *
 *  A     Bidiagonal reduction as returned by ReduceBidiag() where the lower trapezoidal
 *        part, on and below first subdiagonal, holds the product Q. The upper
 *        trapezoidal part holds the product P.
 *
 *  tau   The scalar factors of the elementary reflectors. If flag MULTQ is set then holds
 *        scalar factors for Q. If flag MULTP is set then holds scalar factors for P.
 *        Expected to be column vector is size min(M(A), N(A)).
 *
 *  bits  Indicators, valid bits LEFT, RIGHT, TRANS, MULTQ, MULTP
 *
 *        flags              result
 *        ------------------------------------------
 *        MULTQ,LEFT         C = Q*C     n(A) == m(C)
 *        MULTQ,RIGHT        C = C*Q     n(C) == m(A)
 *        MULTQ,TRANS,LEFT   C = Q.T*C   n(A) == m(C)
 *        MULTQ,TRANS,RIGHT  C = C*Q.T   n(C) == m(A)
 *        MULTP,LEFT         C = P*C     n(A) == m(C)
 *        MULTP,RIGHT        C = C*P     n(C) == m(A)
 *        MULTP,TRANS,LEFT   C = P.T*C   n(A) == m(C)
 *        MULTP,TRANS,RIGHT  C = C*P.T   n(C) == m(A)
 *
 */
func BDMult(C, A, tau, W *cmat.FloatMatrix, flags int, confs ...*gomas.Config) *gomas.Error {
	var Qh, Ch, Ph, tauh cmat.FloatMatrix
	var err *gomas.Error = nil

	// default to multiply from left if side not defined
	if flags&(gomas.LEFT|gomas.RIGHT) == 0 {
		flags = flags | gomas.LEFT
	}
	// if MULTP then flip TRANSPOSE-bit
	if flags&gomas.MULTP != 0 {
		// LQ.P     = G(k)G(k-1)...G(1) and
		// Bidiag.P = G(1)G(2)...G(k)
		//  therefore flip the TRANSPOSE bit.
		if flags&gomas.TRANS != 0 {
			flags &= ^gomas.TRANS
		} else {
			flags |= gomas.TRANS
		}
	}

	if m(A) > n(A) || (m(A) == n(A) && flags&gomas.LOWER == 0) {
		switch flags & (gomas.MULTQ | gomas.MULTP) {
		case gomas.MULTQ:
			tauh.SubMatrix(tau, 0, 0, n(A), 1)
			err = QRMult(C, A, &tauh, W, flags, confs...)

		case gomas.MULTP:
			Ph.SubMatrix(A, 0, 1, n(A)-1, n(A)-1)
			tauh.SubMatrix(tau, 0, 0, n(A)-1, 1)
			if flags&gomas.RIGHT != 0 {
				Ch.SubMatrix(C, 0, 1, m(C), n(C)-1)
			} else {
				Ch.SubMatrix(C, 1, 0, m(C)-1, n(C))
			}
			err = LQMult(&Ch, &Ph, &tauh, W, flags, confs...)
		}
	} else {
		switch flags & (gomas.MULTQ | gomas.MULTP) {
		case gomas.MULTQ:
			Qh.SubMatrix(A, 1, 0, m(A)-1, m(A)-1)
			tauh.SubMatrix(tau, 0, 0, m(A)-1, 1)
			if flags&gomas.RIGHT != 0 {
				Ch.SubMatrix(C, 0, 1, m(C), n(C)-1)
			} else {
				Ch.SubMatrix(C, 1, 0, m(C)-1, n(C))
			}
			err = QRMult(&Ch, &Qh, &tauh, W, flags, confs...)

		case gomas.MULTP:
			tauh.SubMatrix(tau, 0, 0, m(A), 1)
			err = LQMult(C, A, &tauh, W, flags, confs...)
		}
	}
	if err != nil {
		err.Update("BDMult")
	}
	return err
}
Esempio n. 2
0
/*
 * Generates the real orthogonal matrix Q which is defined as the product of K elementary
 * reflectors of order N embedded in matrix A as returned by TRDReduce().
 *
 *   A     On entry tridiagonal reduction as returned by TRDReduce().
 *         On exit the orthogonal matrix Q.
 *
 *  tau    Scalar coefficients of elementary reflectors.
 *
 *  W      Workspace
 *
 *  K      Number of reflectors , 0 < K < N
 *
 *  flags  LOWER or UPPER
 *
 *  confs  Optional blocking configuration
 *
 * If flags has UPPER set then
 *    Q = H(K)...H(1)H(0) where 0 < K < N-1
 *
 * If flags has LOWR set then
 *    Q = H(0)H(1)...H(K) where 0 < K < N-1
 */
func TRDBuild(A, tau, W *cmat.FloatMatrix, K, flags int, confs ...*gomas.Config) *gomas.Error {
	var err *gomas.Error = nil
	var Qh, tauh cmat.FloatMatrix
	var s, d cmat.FloatMatrix

	if K > m(A)-1 {
		K = m(A) - 1
	}

	switch flags & (gomas.LOWER | gomas.UPPER) {
	case gomas.LOWER:
		// Shift Q matrix embedded in A right and fill first column
		// unit column vector
		for j := m(A) - 1; j > 0; j-- {
			s.SubMatrix(A, j, j-1, m(A)-j, 1)
			d.SubMatrix(A, j, j, m(A)-j, 1)
			blasd.Copy(&d, &s)
			A.Set(0, j, 0.0)
		}
		// zero first column and set first entry to one
		d.Column(A, 0)
		blasd.Scale(&d, 0.0)
		d.Set(0, 0, 1.0)

		Qh.SubMatrix(A, 1, 1, m(A)-1, m(A)-1)
		tauh.SubMatrix(tau, 0, 0, m(A)-1, 1)
		err = QRBuild(&Qh, &tauh, W, K, confs...)

	case gomas.UPPER:
		// Shift Q matrix embedded in A left and fill last column
		// unit column vector
		for j := 1; j < m(A); j++ {
			s.SubMatrix(A, 0, j, j, 1)
			d.SubMatrix(A, 0, j-1, j, 1)
			blasd.Copy(&d, &s)
			A.Set(-1, j-1, 0.0)
		}
		// zero last column and set last entry to one
		d.Column(A, m(A)-1)
		blasd.Scale(&d, 0.0)
		d.Set(-1, 0, 1.0)

		Qh.SubMatrix(A, 0, 0, m(A)-1, m(A)-1)
		tauh.SubMatrix(tau, 0, 0, m(A)-1, 1)
		err = QLBuild(&Qh, &tauh, W, K, confs...)
	}
	if err != nil {
		err.Update("TRDBuild")
	}
	return err
}
Esempio n. 3
0
/*
 * Generate one of the orthogonal matrices Q or P.T determined by BDReduce() when
 * reducing a real matrix A to bidiagonal form. Q and P.T are defined as products
 * elementary reflectors H(i) or G(i) respectively.
 *
 * Orthogonal matrix Q is generated if flag WANTQ is set. And matrix P respectively
 * if flag WANTP is set.
 */
func BDBuild(A, tau, W *cmat.FloatMatrix, K, flags int, confs ...*gomas.Config) *gomas.Error {
	var Qh, Ph, tauh, d, s cmat.FloatMatrix
	var err *gomas.Error = nil

	if m(A) == 0 || n(A) == 0 {
		return nil
	}

	if m(A) > n(A) || (m(A) == n(A) && flags&gomas.LOWER == 0) {
		switch flags & (gomas.WANTQ | gomas.WANTP) {
		case gomas.WANTQ:
			tauh.SubMatrix(tau, 0, 0, n(A), 1)
			err = QRBuild(A, &tauh, W, K, confs...)

		case gomas.WANTP:
			// Shift P matrix embedded in A down and fill first column and row
			// to unit vector
			for j := n(A) - 1; j > 0; j-- {
				s.SubMatrix(A, j-1, j, 1, n(A)-j)
				d.SubMatrix(A, j, j, 1, n(A)-j)
				blasd.Copy(&d, &s)
				A.Set(j, 0, 0.0)
			}
			// zero  first row and set first entry to one
			d.Row(A, 0)
			blasd.Scale(&d, 0.0)
			d.Set(0, 0, 1.0)

			Ph.SubMatrix(A, 1, 1, n(A)-1, n(A)-1)
			tauh.SubMatrix(tau, 0, 0, n(A)-1, 1)
			if K > n(A)-1 {
				K = n(A) - 1
			}
			err = LQBuild(&Ph, &tauh, W, K, confs...)
		}
	} else {
		switch flags & (gomas.WANTQ | gomas.WANTP) {
		case gomas.WANTQ:
			// Shift Q matrix embedded in A right and fill first column and row
			// to unit vector
			for j := m(A) - 1; j > 0; j-- {
				s.SubMatrix(A, j, j-1, m(A)-j, 1)
				d.SubMatrix(A, j, j, m(A)-j, 1)
				blasd.Copy(&d, &s)
				A.Set(0, j, 0.0)
			}
			// zero first column and set first entry to one
			d.Column(A, 0)
			blasd.Scale(&d, 0.0)
			d.Set(0, 0, 1.0)

			Qh.SubMatrix(A, 1, 1, m(A)-1, m(A)-1)
			tauh.SubMatrix(tau, 0, 0, m(A)-1, 1)
			if K > m(A)-1 {
				K = m(A) - 1
			}
			err = QRBuild(&Qh, &tauh, W, K, confs...)

		case gomas.WANTP:
			tauh.SubMatrix(tau, 0, 0, m(A), 1)
			err = LQBuild(A, &tauh, W, K, confs...)
		}
	}
	if err != nil {
		err.Update("BDBuild")
	}
	return err
}