// 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 }
// 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 }