Beispiel #1
0
// Compute
//      Y = alpha*A*X + beta*Y
//      Y = alpha*A.T*X + beta*Y  ; flags = TRANSA
//
//    A is M*N or N*M generic matrix,
//    X is row or column vector of length N
//    Y is row or column vector of legth M.
//
// MVMult is vector orientation agnostic. It does not matter if Y, X are row or
// column vectors, they are always handled as if they were column vectors.
func MVMult(Y, A, X *matrix.FloatMatrix, alpha, beta float64, flags Flags) error {

	if A.Rows() == 0 || A.Cols() == 0 {
		return nil
	}
	if Y.Rows() != 1 && Y.Cols() != 1 {
		return errors.New("Y not a vector.")
	}
	if X.Rows() != 1 && X.Cols() != 1 {
		return errors.New("X not a vector.")
	}

	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Yr := Y.FloatArray()
	incY := 1
	lenY := Y.NumElements()
	if Y.Rows() == 1 {
		// row vector
		incY = Y.LeadingIndex()
	}
	Xr := X.FloatArray()
	incX := 1
	lenX := X.NumElements()
	if X.Rows() == 1 {
		// row vector
		incX = X.LeadingIndex()
	}
	// NOTE: This could diveded to parallel tasks by rows.
	calgo.DMultMV(Yr, Ar, Xr, alpha, beta, calgo.Flags(flags), incY, ldA, incX,
		0, lenX, 0, lenY, vpLen, mB)
	return nil
}
Beispiel #2
0
// Y = alpha*A.T*X + beta*Y
func MVMultTransA(Y, A, X *matrix.FloatMatrix, alpha, beta float64) error {

	if Y.Rows() != 1 && Y.Cols() != 1 {
		return errors.New("Y not a vector.")
	}
	if X.Rows() != 1 && X.Cols() != 1 {
		return errors.New("X not a vector.")
	}

	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Yr := Y.FloatArray()
	incY := 1
	lenY := Y.Rows()
	if Y.Rows() == 1 {
		// row vector
		incY = Y.LeadingIndex()
		lenY = Y.Cols()
	}
	Xr := X.FloatArray()
	incX := 1
	lenX := X.Rows()
	if X.Rows() == 1 {
		// row vector
		incX = X.LeadingIndex()
		lenX = X.Cols()
	}
	calgo.DMultMV(Yr, Ar, Xr, alpha, beta, calgo.TRANSA, incY, ldA, incX,
		0, lenX, 0, lenY, vpLen, mB)
	return nil
}