예제 #1
0
파일: deprec.go 프로젝트: hrautila/matops
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
}
예제 #2
0
파일: deprec.go 프로젝트: hrautila/matops
// 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
}
예제 #3
0
파일: deprec.go 프로젝트: hrautila/matops
// 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
}
예제 #4
0
파일: mmult.go 프로젝트: hrautila/matops
// 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
}
예제 #5
0
파일: misc.go 프로젝트: hrautila/cvx
/*
   Returns x' * J * y, where J = [1, 0; 0, -I].
*/
func jdot(x, y *matrix.FloatMatrix, n, offsetx, offsety int) float64 {
	if n <= 0 {
		n = x.NumElements()
	}
	a := blas.DotFloat(x, y, &la_.IOpt{"n", n - 1}, &la_.IOpt{"offsetx", offsetx + 1},
		&la_.IOpt{"offsety", offsety + 1})
	return x.GetIndex(offsetx)*y.GetIndex(offsety) - a
}
예제 #6
0
파일: testqcl1.go 프로젝트: hrautila/go.opt
func (g *matrixFs) Gf(x, y *matrix.FloatMatrix, alpha, beta float64, trans linalg.Option) error {
	//
	minor := 0
	if !checkpnt.MinorEmpty() {
		minor = checkpnt.MinorTop()
	} else {
		loopg += 1
		minor = loopg
	}
	checkpnt.Check("00-Gfunc", minor)

	m, n := g.A.Size()
	y.Scale(beta)

	// x_n = x[:n]
	//x_n := matrix.FloatVector(x.FloatArray()[:n])
	x_n := x.SubMatrix(0, 0, n, 1).Copy()

	// x_n_2n = x[n:2*n]
	//x_n_2n := matrix.FloatVector(x.FloatArray()[n : 2*n])
	x_n_2n := x.SubMatrix(n, 0, n, 1).Copy()

	if linalg.Equal(trans, linalg.OptNoTrans) {
		// y += alpha * G * x

		// y[:n] += alpha * (x[:n] - x[n:2*n])
		y_n := matrix.Minus(x_n, x_n_2n).Scale(alpha)
		y.SubMatrix(0, 0, n, 1).Plus(y_n)
		//y.AddIndexes(matrix.Indexes(n), y_n.FloatArray())

		// y[n:2*n] += alpha * (-x[:n] - x[n:2*n]) = -alpha * (x[:n]+x[n:2*n])
		y_n = matrix.Plus(x_n, x_n_2n).Scale(-alpha)
		y.SubMatrix(n, 0, n, 1).Plus(y_n)
		//y.AddIndexes(matrix.Indexes(n, 2*n), y_n.FloatArray())

		// y[2*n+1:] += -alpha * A * x[:n]
		y_2n := matrix.Times(g.A, x_n).Scale(-alpha)
		//y.AddIndexes(matrix.Indexes(2*n+1, y.NumElements()), y_2n.FloatArray())
		y.SubMatrix(2*n+1, 0, y_2n.NumElements(), 1).Plus(y_2n)
	} else {
		// x_m = x[-m:]
		//x_m := matrix.FloatVector(x.FloatArray()[x.NumElements()-m:])
		x_m := x.SubMatrix(x.NumElements()-m, 0)

		// x_tmp = (x[:n] - x[n:2*n] - A.T * x[-m:])
		x_tmp := matrix.Minus(x_n, x_n_2n, matrix.Times(g.A.Transpose(), x_m))

		// y[:n] += alpha * (x[:n] - x[n:2*n] - A.T * x[-m:])
		//y.AddIndexes(matrix.Indexes(n), x_tmp.Scale(alpha).FloatArray())
		y.SubMatrix(0, 0, n, 1).Plus(x_tmp.Scale(alpha))

		x_tmp = matrix.Plus(x_n, x_n_2n).Scale(-alpha)
		//y.AddIndexes(matrix.Indexes(n, y.NumElements()), x_tmp.FloatArray())
		y.SubMatrix(n, 0).Plus(x_tmp)
	}
	checkpnt.Check("10-Gfunc", minor)
	return nil
}
예제 #7
0
파일: mmult.go 프로젝트: hrautila/matops
// 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
}
예제 #8
0
파일: misc.go 프로젝트: hrautila/cvx
/*
   Returns sqrt(x' * J * x) where J = [1, 0; 0, -I], for a vector
   x in a second order cone.
*/
func jnrm2(x *matrix.FloatMatrix, n, offset int) float64 {
	/*DEBUGGED*/
	if n <= 0 {
		n = x.NumElements()
	}
	if offset < 0 {
		offset = 0
	}
	a := blas.Nrm2Float(x, &la_.IOpt{"n", n - 1}, &la_.IOpt{"offset", offset + 1})
	fst := x.GetIndex(offset)
	return math.Sqrt(fst-a) * math.Sqrt(fst+a)
}
예제 #9
0
func _TestPartition2D(t *testing.T) {
	var ATL, ATR, ABL, ABR, As matrix.FloatMatrix
	var A00, a01, A02, a10, a11, a12, A20, a21, A22 matrix.FloatMatrix

	A := matrix.FloatZeros(6, 6)
	As.SubMatrixOf(A, 1, 1, 4, 4)
	As.SetIndexes(1.0)
	partition2x2(&ATL, &ATR, &ABL, &ABR, &As, 0)
	t.Logf("ATL:\n%v\n", &ATL)

	for ATL.Rows() < As.Rows() {
		repartition2x2to3x3(&ATL,
			&A00, &a01, &A02,
			&a10, &a11, &a12,
			&A20, &a21, &A22, &As, 1)
		t.Logf("m(a12)=%d [%d], m(a11)=%d\n", a12.Cols(), a12.NumElements(), a11.NumElements())
		a11.Add(1.0)
		a21.Add(-2.0)

		continue3x3to2x2(&ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, &As)
	}
	t.Logf("A:\n%v\n", A)
}
예제 #10
0
파일: diag.go 프로젝트: hrautila/matops
/*
 * Generic rank update of diagonal matrix.
 *   diag(D) = diag(D) + alpha * x * y.T
 *
 * Arguments:
 *   D     N element column or row vector or N-by-N matrix
 *
 *   x, y  N element vectors
 *
 *   alpha scalar
 */
func MVUpdateDiag(D, x, y *matrix.FloatMatrix, alpha float64) error {
	var d *matrix.FloatMatrix
	var dvec matrix.FloatMatrix

	if !isVector(x) || !isVector(y) {
		return errors.New("x, y not vectors")
	}
	if D.Rows() > 0 && D.Cols() == D.Rows() {
		D.Diag(&dvec)
		d = &dvec
	} else if isVector(D) {
		d = D
	} else {
		return errors.New("D not a diagonal")
	}

	N := d.NumElements()
	for k := 0; k < N; k++ {
		val := d.GetIndex(k)
		val += x.GetIndex(k) * y.GetIndex(k) * alpha
		d.SetIndex(k, val)
	}
	return nil
}