Beispiel #1
0
func solveMVTest(t *testing.T, A, X0 *matrix.FloatMatrix, flags Flags, bN, bNB int) {
	X1 := X0.Copy()

	uplo := linalg.OptUpper
	diag := linalg.OptNonUnit
	if flags&LOWER != 0 {
		uplo = linalg.OptLower
	}
	if flags&UNIT != 0 {
		diag = linalg.OptUnit
	}

	blas.TrsvFloat(A, X0, uplo, diag)

	Ar := A.FloatArray()
	Xr := X1.FloatArray()
	if bN == bNB {
		DSolveUnblkMV(Xr, Ar, flags, 1, A.LeadingIndex(), bN)
	} else {
		DSolveBlkMV(Xr, Ar, flags, 1, A.LeadingIndex(), bN, bNB)
	}
	ok := X1.AllClose(X0)
	t.Logf("X1 == X0: %v\n", ok)
	if !ok && bN < 8 {
		t.Logf("A=\n%v\n", A)
		t.Logf("X0=\n%v\n", X0)
		t.Logf("blas: X0\n%v\n", X0)
		t.Logf("X1:\n%v\n", X1)
	}
}
Beispiel #2
0
func trmvTest(t *testing.T, A *matrix.FloatMatrix, flags Flags, nb int) bool {
	N := A.Cols()
	//S := 0
	//E := A.Cols()
	X0 := matrix.FloatWithValue(A.Rows(), 1, 2.0)
	X1 := X0.Copy()

	trans := linalg.OptNoTrans
	if flags&TRANS != 0 {
		trans = linalg.OptTrans
	}
	diag := linalg.OptNonUnit
	if flags&UNIT != 0 {
		diag = linalg.OptUnit
	}
	uplo := linalg.OptUpper
	if flags&LOWER != 0 {
		uplo = linalg.OptLower
	}

	blas.TrmvFloat(A, X0, uplo, diag, trans)

	Ar := A.FloatArray()
	Xr := X1.FloatArray()
	if nb == 0 {
		DTrimvUnblkMV(Xr, Ar, flags, 1, A.LeadingIndex(), N)
	}
	result := X0.AllClose(X1)
	t.Logf("   X0 == X1: %v\n", result)
	if !result && A.Rows() < 8 {
		t.Logf("  BLAS TRMV X0:\n%v\n", X0)
		t.Logf("  DTrmv X1:\n%v\n", X1)
	}
	return result
}
Beispiel #3
0
// Y := alpha * X + Y
func Axpy(Y, X *matrix.FloatMatrix, alpha float64) {
	if X == nil || Y == nil {
		return
	}
	if !isVector(X) {
		return
	}
	if !isVector(Y) {
		return
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Cols() != 1 {
		// Row vector
		incX = X.LeadingIndex()
	}
	Yr := Y.FloatArray()
	incY := 1
	if Y.Cols() != 1 {
		// Row vector
		incY = Y.LeadingIndex()
	}
	calgo.DAxpy(Xr, Yr, alpha, incX, incY, X.NumElements())
	return
}
Beispiel #4
0
func syrkTest(t *testing.T, C, A *matrix.FloatMatrix, flags Flags, vlen, nb int) bool {
	//var B0 *matrix.FloatMatrix
	P := A.Cols()
	S := 0
	E := C.Rows()
	C0 := C.Copy()

	trans := linalg.OptNoTrans
	if flags&TRANSA != 0 {
		trans = linalg.OptTrans
		P = A.Rows()
	}
	uplo := linalg.OptUpper
	if flags&LOWER != 0 {
		uplo = linalg.OptLower
	}

	blas.SyrkFloat(A, C0, 1.0, 1.0, uplo, trans)
	if A.Rows() < 8 {
		//t.Logf("..A\n%v\n", A)
		t.Logf("  BLAS C0:\n%v\n", C0)
	}

	Ar := A.FloatArray()
	Cr := C.FloatArray()
	DSymmRankBlk(Cr, Ar, 1.0, 1.0, flags, C.LeadingIndex(), A.LeadingIndex(),
		P, S, E, vlen, nb)
	result := C0.AllClose(C)
	t.Logf("   C0 == C: %v\n", result)
	if A.Rows() < 8 {
		t.Logf("  DMRank C:\n%v\n", C)
	}
	return result
}
Beispiel #5
0
// Swap X and Y.
func Swap(X, Y *matrix.FloatMatrix) {
	if X == nil || Y == nil {
		return
	}
	if X.NumElements() == 0 || Y.NumElements() == 0 {
		return
	}
	if !isVector(X) {
		return
	}
	if !isVector(Y) {
		return
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Cols() != 1 {
		// Row vector
		incX = X.LeadingIndex()
	}
	Yr := Y.FloatArray()
	incY := 1
	if Y.Cols() != 1 {
		// Row vector
		incY = Y.LeadingIndex()
	}
	calgo.DSwap(Xr, Yr, incX, incY, X.NumElements())
}
Beispiel #6
0
// Solve multiple right sides. If flags&UNIT then A diagonal is assumed to
// to unit and is not referenced. (blas.TRSM)
//      alpha*B = A.-1*B if flags&LEFT
//      alpha*B = A.-T*B if flags&(LEFT|TRANS)
//      alpha*B = B*A.-1 if flags&RIGHT
//      alpha*B = B*A.-T if flags&(RIGHT|TRANS)
//
// Matrix A is N*N triangular matrix defined with flags bits as follow
//  LOWER       non-unit lower triangular
//  LOWER|UNIT  unit lower triangular
//  UPPER       non-unit upper triangular
//  UPPER|UNIT  unit upper triangular
//
// Matrix B is N*P if flags&LEFT or P*N if flags&RIGHT.
//
func SolveTrm(B, A *matrix.FloatMatrix, alpha float64, flags Flags) error {

	ok := true
	empty := false
	br, bc := B.Size()
	ar, ac := A.Size()
	switch flags & (LEFT | RIGHT) {
	case LEFT:
		empty = br == 0
		ok = br == ac && ac == ar
	case RIGHT:
		empty = bc == 0
		ok = bc == ar && ac == ar
	}
	if empty {
		return nil
	}
	if !ok {
		return onError("A, B size mismatch")
	}

	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Br := B.FloatArray()
	ldB := B.LeadingIndex()

	E := bc
	if flags&RIGHT != 0 {
		E = br
	}
	// if more workers available can divide to tasks by B columns if flags&LEFT or by
	// B rows if flags&RIGHT.
	calgo.DSolveBlk(Br, Ar, alpha, calgo.Flags(flags), ldB, ldA, ac, 0, E, nB)
	return nil
}
Beispiel #7
0
// A = alpha*A + beta*B
// A = alpha*A + beta*B.T  if flags&TRANSB
func ScalePlus(A, B *matrix.FloatMatrix, alpha, beta float64, flags Flags) error {

	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Br := B.FloatArray()
	ldB := B.LeadingIndex()
	S := 0
	L := A.Cols()
	R := 0
	E := A.Rows()
	calgo.DScalePlus(Ar, Br, alpha, beta, calgo.Flags(flags), ldA, ldB, S, L, R, E)
	return nil
}
Beispiel #8
0
func trmmTest(t *testing.T, A *matrix.FloatMatrix, flags Flags, nb int) bool {
	var B0 *matrix.FloatMatrix
	N := A.Cols()
	S := 0
	E := A.Cols()
	side := linalg.OptLeft
	if flags&RIGHT != 0 {
		B0 = matrix.FloatWithValue(2, A.Rows(), 2.0)
		side = linalg.OptRight
		E = B0.Rows()
	} else {
		B0 = matrix.FloatWithValue(A.Rows(), 2, 2.0)
		E = B0.Cols()
	}
	B1 := B0.Copy()

	trans := linalg.OptNoTrans
	if flags&TRANSA != 0 {
		trans = linalg.OptTransA
	}
	diag := linalg.OptNonUnit
	if flags&UNIT != 0 {
		diag = linalg.OptUnit
	}
	uplo := linalg.OptUpper
	if flags&LOWER != 0 {
		uplo = linalg.OptLower
	}

	blas.TrmmFloat(A, B0, 1.0, uplo, diag, trans, side)
	if A.Rows() < 8 {
		//t.Logf("..A\n%v\n", A)
		t.Logf("  BLAS B0:\n%v\n", B0)
	}

	Ar := A.FloatArray()
	Br := B1.FloatArray()
	if nb != 0 {
		DTrmmBlk(Br, Ar, 1.0, flags, B1.LeadingIndex(), A.LeadingIndex(),
			N, S, E, nb)
	} else {
		DTrmmUnblk(Br, Ar, 1.0, flags, B1.LeadingIndex(), A.LeadingIndex(),
			N, S, E, 0)
	}
	result := B0.AllClose(B1)
	t.Logf("   B0 == B1: %v\n", result)
	if A.Rows() < 8 {
		t.Logf("  DTrmm B1:\n%v\n", B1)
	}
	return result
}
Beispiel #9
0
// index of max |x|
func IAMax(X *matrix.FloatMatrix) int {
	if X == nil {
		return -1
	}
	if !isVector(X) {
		return -1
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Cols() != 1 {
		// Row vector
		incX = X.LeadingIndex()
	}
	return calgo.DIAMax(Xr, incX, X.NumElements())
}
Beispiel #10
0
// Scaling with scalar: X = alpha * X
func Scale(X *matrix.FloatMatrix, alpha float64) {
	if X == nil || X.NumElements() == 0 {
		return
	}
	if !isVector(X) {
		return
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Cols() != 1 {
		// Row vector
		incX = X.LeadingIndex()
	}
	calgo.DScal(Xr, alpha, incX, X.NumElements())
}
Beispiel #11
0
// sum(|x|)
func ASum(X *matrix.FloatMatrix) float64 {
	if X == nil {
		return math.NaN()
	}
	if !isVector(X) {
		return math.NaN()
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Cols() != 1 {
		// Row vector
		incX = X.LeadingIndex()
	}
	return calgo.DAsum(Xr, incX, X.NumElements())
}
Beispiel #12
0
/*
 * Compute
 *   C = C*diag(D)      flags & RIGHT == true
 *   C = diag(D)*C      flags & LEFT  == true
 *
 * Arguments
 *   C     M-by-N matrix if flags&RIGHT == true or N-by-M matrix if flags&LEFT == true
 *
 *   D     N element column or row vector or N-by-N matrix
 *
 *   flags Indicator bits, LEFT or RIGHT
 */
func MultDiag(C, D *matrix.FloatMatrix, flags Flags) {
	var c, d0 matrix.FloatMatrix
	if D.Cols() == 1 {
		// diagonal is column vector
		switch flags & (LEFT | RIGHT) {
		case LEFT:
			// scale rows; for each column element-wise multiply with D-vector
			for k := 0; k < C.Cols(); k++ {
				C.SubMatrix(&c, 0, k, C.Rows(), 1)
				c.Mul(D)
			}
		case RIGHT:
			// scale columns
			for k := 0; k < C.Cols(); k++ {
				C.SubMatrix(&c, 0, k, C.Rows(), 1)
				// scale the column
				c.Scale(D.GetAt(k, 0))
			}
		}
	} else {
		// diagonal is row vector
		var d *matrix.FloatMatrix
		if D.Rows() == 1 {
			d = D
		} else {
			D.SubMatrix(&d0, 0, 0, 1, D.Cols(), D.LeadingIndex()+1)
			d = &d0
		}
		switch flags & (LEFT | RIGHT) {
		case LEFT:
			for k := 0; k < C.Rows(); k++ {
				C.SubMatrix(&c, k, 0, 1, C.Cols())
				// scale the row
				c.Scale(d.GetAt(0, k))
			}
		case RIGHT:
			// scale columns
			for k := 0; k < C.Cols(); k++ {
				C.SubMatrix(&c, 0, k, C.Rows(), 1)
				// scale the column
				c.Scale(d.GetAt(0, k))
			}
		}
	}
}
Beispiel #13
0
// A = A + alpha*X*Y.T; A is N*N symmetric, X is row or column vector of length N.
func MVSymmUpdateUpper(A, X *matrix.FloatMatrix, alpha float64) error {

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

	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Xr := X.FloatArray()
	incX := 1
	if X.Rows() == 1 {
		// row vector
		incX = X.LeadingIndex()
	}
	// NOTE: This could diveded to parallel tasks per column.
	calgo.DSymmRankMV(Ar, Xr, alpha, calgo.UPPER, ldA, incX, 0, A.Cols(), 0)
	return nil
}
Beispiel #14
0
// Rank update for symmetric lower or upper matrix (blas.SYRK)
//      C = beta*C + alpha*A*A.T + alpha*A.T*A
func RankUpdateSym(C, A *matrix.FloatMatrix, alpha, beta float64, flags Flags) error {
	if C.Rows() != C.Cols() {
		return onError("C not a square matrix")
	}
	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Cr := C.FloatArray()
	ldC := C.LeadingIndex()
	S := 0
	E := C.Rows()
	P := A.Cols()
	if flags&TRANSA != 0 {
		P = A.Rows()
	}
	// if more workers available C can be divided to blocks [S:E, S:E] along diagonal
	// and updated in separate tasks.
	calgo.DSymmRankBlk(Cr, Ar, alpha, beta, calgo.Flags(flags), ldC, ldA, P, S, E,
		vpLen, nB)
	return nil
}
Beispiel #15
0
// Tridiagonal multiplication; X = A*X
func MVMultTrm(X, A *matrix.FloatMatrix, flags Flags) error {

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

	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Xr := X.FloatArray()
	incX := 1
	if X.Rows() == 1 {
		// row vector
		incX = X.LeadingIndex()
	}
	calgo.DTrimvUnblkMV(Xr, Ar, calgo.Flags(flags), incX, ldA, A.Cols())
	return nil
}
Beispiel #16
0
// Calculate C = alpha*A*B.T + beta*C, C is M*N, A is M*P and B is N*P
func MMMultTransB(C, A, B *matrix.FloatMatrix, alpha, beta float64) error {
	psize := int64(C.NumElements() * A.Cols())
	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Br := B.FloatArray()
	ldB := B.LeadingIndex()
	Cr := C.FloatArray()
	ldC := C.LeadingIndex()
	if nWorker <= 1 || psize <= limitOne {
		calgo.DMult(Cr, Ar, Br, alpha, beta, calgo.TRANSB, ldC, ldA, ldB,
			B.Rows(), 0, C.Cols(), 0, C.Rows(), vpLen, nB, mB)
		return nil
	}

	// here we have more than one worker available
	worker := func(cstart, cend, rstart, rend int, ready chan int) {
		calgo.DMult(Cr, Ar, Br, alpha, beta, calgo.TRANSB, ldC, ldA, ldB, B.Rows(),
			cstart, cend, rstart, rend, vpLen, nB, mB)
		ready <- 1
	}
	colworks, rowworks := divideWork(C.Rows(), C.Cols(), nWorker)
	scheduleWork(colworks, rowworks, C.Cols(), C.Rows(), worker)
	//scheduleWork(colworks, rowworks, worker)
	return nil
}
Beispiel #17
0
// Calculate C = alpha*A*B + beta*C, C is M*N, A is M*M and B is M*N
func MMSymmUpper(C, A, B *matrix.FloatMatrix, alpha, beta float64) error {

	if A.Rows() != A.Cols() {
		return errors.New("A matrix not square matrix.")
	}
	psize := int64(C.NumElements() * A.Cols())
	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Br := B.FloatArray()
	ldB := B.LeadingIndex()
	Cr := C.FloatArray()
	ldC := C.LeadingIndex()

	if nWorker <= 1 || psize <= limitOne {
		calgo.DMultSymm(Cr, Ar, Br, alpha, beta, calgo.LEFT|calgo.UPPER, ldC, ldA, ldB,
			A.Cols(), 0, C.Cols(), 0, C.Rows(), vpLen, nB, mB)
		return nil
	}
	// here we have more than one worker available
	worker := func(cstart, cend, rstart, rend int, ready chan int) {
		calgo.DMultSymm(Cr, Ar, Br, alpha, beta, calgo.LEFT|calgo.UPPER, ldC, ldA, ldB,
			A.Cols(), cstart, cend, rstart, rend, vpLen, nB, mB)
		ready <- 1
	}
	colworks, rowworks := divideWork(C.Rows(), C.Cols(), nWorker)
	scheduleWork(colworks, rowworks, C.Cols(), C.Rows(), worker)
	return nil
}
Beispiel #18
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
}
Beispiel #19
0
// Add inner product: Z[index] = beta*Z[index] + alpha * X * Y
func AddDot(Z, X, Y *matrix.FloatMatrix, alpha, beta float64, index int) {
	if X == nil || Y == nil {
		return
	}
	if X.NumElements() == 0 || Y.NumElements() == 0 {
		return
	}
	if !isVector(X) {
		return
	}
	if !isVector(Y) {
		return
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Cols() != 1 {
		// Row vector
		incX = X.LeadingIndex()
	}
	Yr := Y.FloatArray()
	incY := 1
	if Y.Cols() != 1 {
		// Row vector
		incY = Y.LeadingIndex()
	}
	Zr := Z.FloatArray()
	incZ := 1
	if Z.Cols() != 1 {
		// Row vector
		incZ = Z.LeadingIndex()
	}
	calgo.DDotSum(Zr[incZ*index:], Xr, Yr, alpha, beta, incZ, incX, incY, X.NumElements())
}
Beispiel #20
0
func Mult0(C, A, B *matrix.FloatMatrix, alpha, beta float64, flags Flags) error {
	if A.Cols() != B.Rows() {
		return errors.New("A.cols != B.rows: size mismatch")
	}
	psize := int64(C.NumElements()) * int64(A.Cols())
	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Br := B.FloatArray()
	ldB := B.LeadingIndex()
	Cr := C.FloatArray()
	ldC := C.LeadingIndex()

	if nWorker <= 1 || psize <= limitOne {
		calgo.DMult0(Cr, Ar, Br, alpha, beta, calgo.Flags(flags), ldC, ldA, ldB, B.Rows(),
			0, C.Cols(), 0, C.Rows(),
			vpLen, nB, mB)
		return nil
	}
	// here we have more than one worker available
	worker := func(cstart, cend, rstart, rend int, ready chan int) {
		calgo.DMult0(Cr, Ar, Br, alpha, beta, calgo.Flags(flags), ldC, ldA, ldB, B.Rows(),
			cstart, cend, rstart, rend, vpLen, nB, mB)
		ready <- 1
	}
	colworks, rowworks := divideWork(C.Rows(), C.Cols(), nWorker)
	scheduleWork(colworks, rowworks, C.Cols(), C.Rows(), worker)
	return nil
}
Beispiel #21
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 #22
0
// Matrix-vector rank update A = A + alpha*X*Y.T
//    A is M*N generic matrix,
//    X is row or column vector of length M
//    Y is row or column vector of legth N.
func MVRankUpdate(A, X, Y *matrix.FloatMatrix, alpha float64) 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
	if Y.Rows() == 1 {
		// row vector
		incY = Y.LeadingIndex()
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Rows() == 1 {
		// row vector
		incX = X.LeadingIndex()
	}
	// NOTE: This could diveded to parallel tasks like matrix-matrix multiplication
	calgo.DRankMV(Ar, Xr, Yr, alpha, ldA, incX, incY, 0, A.Cols(), 0, A.Rows(), 0, 0)
	return nil
}
Beispiel #23
0
// Generic matrix-matrix multpily. (blas.GEMM). Calculates
//   C = beta*C + alpha*A*B     (default)
//   C = beta*C + alpha*A.T*B   flags&TRANSA
//   C = beta*C + alpha*A*B.T   flags&TRANSB
//   C = beta*C + alpha*A.T*B.T flags&(TRANSA|TRANSB)
//
// C is M*N, A is M*P or P*M if flags&TRANSA. B is P*N or N*P if flags&TRANSB.
//
func Mult(C, A, B *matrix.FloatMatrix, alpha, beta float64, flags Flags) error {
	var ok, empty bool
	// error checking must take in account flag values!

	ar, ac := A.Size()
	br, bc := B.Size()
	cr, cc := C.Size()
	switch flags & (TRANSA | TRANSB) {
	case TRANSA | TRANSB:
		empty = ac == 0 || br == 0
		ok = cr == ac && cc == br && ar == bc
	case TRANSA:
		empty = ac == 0 || bc == 0
		ok = cr == ac && cc == bc && ar == br
	case TRANSB:
		empty = ar == 0 || br == 0
		ok = cr == ar && cc == br && ac == bc
	default:
		empty = ar == 0 || bc == 0
		ok = cr == ar && cc == bc && ac == br

	}
	if empty {
		return nil
	}
	if !ok {
		return errors.New("Mult: size mismatch")
	}

	psize := int64(C.NumElements()) * int64(A.Cols())
	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Br := B.FloatArray()
	ldB := B.LeadingIndex()
	Cr := C.FloatArray()
	ldC := C.LeadingIndex()

	// matrix A, B common dimension
	P := A.Cols()
	if flags&TRANSA != 0 {
		P = A.Rows()
	}

	if nWorker <= 1 || psize <= limitOne {
		calgo.DMult(Cr, Ar, Br, alpha, beta, calgo.Flags(flags), ldC, ldA, ldB, P,
			0, C.Cols(), 0, C.Rows(),
			vpLen, nB, mB)
		return nil
	}
	// here we have more than one worker available
	worker := func(cstart, cend, rstart, rend int, ready chan int) {
		calgo.DMult(Cr, Ar, Br, alpha, beta, calgo.Flags(flags), ldC, ldA, ldB, P,
			cstart, cend, rstart, rend, vpLen, nB, mB)
		ready <- 1
	}
	colworks, rowworks := divideWork(C.Rows(), C.Cols(), nWorker)
	scheduleWork(colworks, rowworks, C.Cols(), C.Rows(), worker)
	return nil
}
Beispiel #24
0
func update(t *testing.T, Y1, Y2, C1, C2, T, W *matrix.FloatMatrix) {
	if W.Rows() != C1.Cols() {
		panic("W.Rows != C1.Cols")
	}
	// W = C1.T
	ScalePlus(W, C1, 0.0, 1.0, TRANSB)
	//fmt.Printf("W = C1.T:\n%v\n", W)
	// W = C1.T*Y1
	//MultTrm(W, Y1, 1.0, LOWER|UNIT|RIGHT)
	Wr := W.FloatArray()
	Y1r := Y1.FloatArray()
	ldW := W.LeadingIndex()
	ldY := Y1.LeadingIndex()
	calgo.DTrmmUnblk(Wr, Y1r, 1.0, calgo.Flags(LOWER|UNIT|RIGHT),
		ldW, ldY, Y1.Cols(), 0, W.Rows(), 0)
	t.Logf("W = C1.T*Y1:\n%v\n", W)
	// W = W + C2.T*Y2
	Mult(W, C2, Y2, 1.0, 1.0, TRANSA)
	t.Logf("W = W + C2.T*Y2:\n%v\n", W)

	// --- here: W == C.T*Y ---
	// W = W*T
	MultTrm(W, T, 1.0, UPPER|RIGHT)
	t.Logf("W = C.T*Y*T:\n%v\n", W)

	// --- here: W == C.T*Y*T ---
	// C2 = C2 - Y2*W.T
	Mult(C2, Y2, W, -1.0, 1.0, TRANSB)
	t.Logf("C2 = C2 - Y2*W.T:\n%v\n", C2)
	//  W = Y1*W.T ==> W.T = W*Y1.T
	MultTrm(W, Y1, 1.0, LOWER|UNIT|TRANSA|RIGHT)
	t.Logf("W.T = W*Y1.T:\n%v\n", W)

	// C1 = C1 - W.T
	ScalePlus(C1, W, 1.0, -1.0, TRANSB)
	//fmt.Printf("C1 = C1 - W.T:\n%v\n", C1)

	// --- here: C = (I - Y*T*Y.T).T * C ---
}
Beispiel #25
0
// Symmetric matrix multiply. (blas.SYMM)
//   C = beta*C + alpha*A*B     (default)
//   C = beta*C + alpha*A.T*B   flags&TRANSA
//   C = beta*C + alpha*A*B.T   flags&TRANSB
//   C = beta*C + alpha*A.T*B.T flags&(TRANSA|TRANSB)
//
// C is N*P, A is N*N symmetric matrix. B is N*P or P*N if flags&TRANSB.
//
func MultSym(C, A, B *matrix.FloatMatrix, alpha, beta float64, flags Flags) error {
	var ok, empty bool

	ar, ac := A.Size()
	br, bc := B.Size()
	cr, cc := C.Size()
	switch flags & (TRANSA | TRANSB) {
	case TRANSA | TRANSB:
		empty = ac == 0 || br == 0
		ok = ar == ac && cr == ac && cc == br && ar == bc
	case TRANSA:
		empty = ac == 0 || bc == 0
		ok = ar == ac && cr == ac && cc == bc && ar == br
	case TRANSB:
		empty = ar == 0 || br == 0
		ok = ar == ac && cr == ar && cc == br && ac == bc
	default:
		empty = ar == 0 || bc == 0
		ok = ar == ac && cr == ar && cc == bc && ac == br
	}
	if empty {
		return nil
	}
	if !ok {
		return errors.New("MultSym: size mismatch")
	}
	/*
	   if A.Rows() != A.Cols() {
	       return errors.New("A matrix not square matrix.");
	   }
	   if A.Cols() != B.Rows() {
	       return errors.New("A.cols != B.rows: size mismatch")
	   }
	*/
	psize := int64(C.NumElements()) * int64(A.Cols())
	Ar := A.FloatArray()
	ldA := A.LeadingIndex()
	Br := B.FloatArray()
	ldB := B.LeadingIndex()
	Cr := C.FloatArray()
	ldC := C.LeadingIndex()

	if nWorker <= 1 || psize <= limitOne {
		calgo.DMultSymm(Cr, Ar, Br, alpha, beta, calgo.Flags(flags), ldC, ldA, ldB,
			A.Cols(), 0, C.Cols(), 0, C.Rows(), vpLen, nB, mB)
		return nil
	}
	// here we have more than one worker available
	worker := func(cstart, cend, rstart, rend int, ready chan int) {
		calgo.DMultSymm(Cr, Ar, Br, alpha, beta, calgo.Flags(flags), ldC, ldA, ldB,
			A.Cols(), cstart, cend, rstart, rend, vpLen, nB, mB)
		ready <- 1
	}
	colworks, rowworks := divideWork(C.Rows(), C.Cols(), nWorker)
	scheduleWork(colworks, rowworks, C.Cols(), C.Rows(), worker)
	return nil
}
Beispiel #26
0
// Inner product: alpha * X * Y
func Dot(X, Y *matrix.FloatMatrix, alpha float64) float64 {
	if X == nil || Y == nil {
		return math.NaN()
	}
	if !isVector(X) {
		return math.NaN()
	}
	if !isVector(Y) {
		return math.NaN()
	}
	Xr := X.FloatArray()
	incX := 1
	if X.Cols() != 1 {
		// Row vector
		incX = X.LeadingIndex()
	}
	Yr := Y.FloatArray()
	incY := 1
	if Y.Cols() != 1 {
		// Row vector
		incY = Y.LeadingIndex()
	}
	return calgo.DDot(Xr, Yr, alpha, incX, incY, X.NumElements())
}
Beispiel #27
0
func trsmSolve(t *testing.T, A *matrix.FloatMatrix, flags Flags, rand bool, nrhs, nb int) bool {
	var B0 *matrix.FloatMatrix
	side := linalg.OptLeft
	trans := linalg.OptNoTrans
	N := A.Cols()
	S := 0
	E := A.Rows()
	_ = S
	_ = E
	if flags&RIGHT != 0 {
		if rand {
			B0 = matrix.FloatNormal(nrhs, A.Rows())
		} else {
			B0 = matrix.FloatWithValue(nrhs, A.Rows(), 2.0)
		}
		side = linalg.OptRight
		E = B0.Rows()
	} else {
		if rand {
			B0 = matrix.FloatNormal(A.Rows(), nrhs)
		} else {
			B0 = matrix.FloatWithValue(A.Rows(), nrhs, 2.0)
		}
		E = B0.Cols()
	}
	B1 := B0.Copy()
	diag := linalg.OptNonUnit
	if flags&UNIT != 0 {
		diag = linalg.OptUnit
	}
	uplo := linalg.OptUpper
	if flags&LOWER != 0 {
		uplo = linalg.OptLower
	}
	if flags&TRANSA != 0 {
		trans = linalg.OptTransA
	}
	blas.TrsmFloat(A, B0, 1.0, uplo, diag, side, trans)

	Ar := A.FloatArray()
	Br := B1.FloatArray()
	if nb == 0 || nb == N {
		DSolveUnblk(Br, Ar, 1.0, flags, B1.LeadingIndex(), A.LeadingIndex(), N, S, E)
	} else {
		DSolveBlk(Br, Ar, 1.0, flags, B1.LeadingIndex(), A.LeadingIndex(), N, S, E, nb)
	}
	result := B1.AllClose(B0)
	t.Logf("B1 == B0: %v\n", result)
	if !result {
		if nrhs < 10 {
			t.Logf("blas: B0\n%v\n", B0)
			t.Logf("B1:\n%v\n", B1)
		} else {
			b0 := B0.FloatArray()
			b1 := B1.FloatArray()
			for k := 0; k < len(b0); k++ {
				if !isClose(b0[k], b1[k]) {
					t.Logf("first divergences at %d ... col %d, row %d\n", k, k/B0.Rows(), k%B0.Rows())
					break
				}
			}
		}
	}
	return result
}
Beispiel #28
0
func TestMultMVTransASmall(t *testing.T) {
	data6 := [][]float64{
		[]float64{-1.59e+00, 6.56e-02, 2.14e-01, 6.79e-01, 2.93e-01, 5.24e-01},
		[]float64{4.28e-01, 1.57e-01, 3.81e-01, 2.19e-01, 2.97e-01, 2.83e-02},
		[]float64{3.02e-01, 9.70e-02, 3.18e-01, 2.03e-01, 7.53e-01, 1.58e-01},
		[]float64{1.99e-01, 3.01e-01, 4.69e-01, 3.61e-01, 2.07e-01, 6.07e-01},
		[]float64{1.93e-01, 5.15e-01, 2.83e-01, 5.71e-01, 8.65e-01, 9.75e-01},
		[]float64{3.13e-01, 8.14e-01, 2.93e-01, 8.62e-01, 6.97e-01, 7.95e-02}}
	data5 := [][]float64{
		[]float64{1.57e-01, 3.81e-01, 2.19e-01, 2.97e-01, 2.83e-02},
		[]float64{9.70e-02, 3.18e-01, 2.03e-01, 7.53e-01, 1.58e-01},
		[]float64{3.01e-01, 4.69e-01, 3.61e-01, 2.07e-01, 6.07e-01},
		[]float64{5.15e-01, 2.83e-01, 5.71e-01, 8.65e-01, 9.75e-01},
		[]float64{8.14e-01, 2.93e-01, 8.62e-01, 6.97e-01, 7.95e-02}}
	data2 := []float64{4.28e-01, 3.02e-01, 1.99e-01, 1.93e-01, 3.13e-01}

	bM := 5
	bN := 4
	nb := 2
	//A := matrix.FloatNormal(bN, bM)
	//X := matrix.FloatWithValue(bN, 1, 1.0)

	A := matrix.FloatMatrixFromTable(data5, matrix.RowOrder)
	X := matrix.FloatNew(5, 1, data2)
	bM = A.Rows()
	bN = A.Cols()
	Ym := matrix.FloatZeros(3, bM)
	Y1 := matrix.FloatZeros(bM, 1)
	Y0 := matrix.FloatZeros(bM, 1)

	Ar := A.FloatArray()
	Xr := X.FloatArray()
	Y1r := Y1.FloatArray()

	blas.GemvFloat(A, X, Y0, 1.0, 1.0, linalg.OptTrans)

	DMultMV(Y1r, Ar, Xr, 1.0, 1.0, TRANSA, 1, A.LeadingIndex(), 1, 0, bN, 0, bM, nb, nb)
	ok := Y0.AllClose(Y1)
	t.Logf("Y0 == Y1: %v\n", ok)
	if ok || !ok {
		t.Logf("blas: Y=A.T*X\n%v\n", Y0)
		t.Logf("Y1: Y1 = A*X\n%v\n", Y1)
	}

	// zero Y0, Y1
	Y0.Scale(0.0)
	Y1.Scale(0.0)

	// test with matrix view; A is view
	var A0 matrix.FloatMatrix
	A6 := matrix.FloatMatrixFromTable(data6, matrix.RowOrder)
	A0.SubMatrixOf(A6, 1, 1)

	blas.GemvFloat(&A0, X, Y0, 1.0, 1.0, linalg.OptTrans)

	Ar = A0.FloatArray()
	DMultMV(Y1r, Ar, Xr, 1.0, 1.0, TRANSA, 1, A0.LeadingIndex(), 1, 0, bN, 0, bM, nb, nb)
	ok = Y0.AllClose(Y1)
	t.Logf("lda>rows: Y0 == Y1: %v\n", ok)
	if ok || !ok {
		t.Logf("blas: Y=A.T*X\n%v\n", Y0)
		t.Logf("Y1: Y1 = A*X\n%v\n", Y1)
	}

	// Y is view too.
	Y1.SubMatrixOf(Ym, 0, 0, 1, bM)
	Y1r = Y1.FloatArray()
	DMultMV(Y1r, Ar, Xr, 1.0, 1.0, TRANSA, Y1.LeadingIndex(), A0.LeadingIndex(), 1, 0, bN, 0, bM, nb, nb)
	ok = Y0.AllClose(Y1.Transpose())
	t.Logf("Y0 == Y1 row: %v\n", ok)
	t.Logf("row Y1: %v\n", Y1)
}