예제 #1
0
func _TestRankSmall(t *testing.T) {
	bM := 5
	bN := 5
	//bP := 5
	Adata := [][]float64{
		[]float64{1.0, 1.0, 1.0, 1.0, 1.0},
		[]float64{2.0, 2.0, 2.0, 2.0, 2.0},
		[]float64{3.0, 3.0, 3.0, 3.0, 3.0},
		[]float64{4.0, 4.0, 4.0, 4.0, 4.0},
		[]float64{5.0, 5.0, 5.0, 5.0, 5.0}}

	A := matrix.FloatMatrixFromTable(Adata, matrix.RowOrder)
	A0 := matrix.FloatMatrixFromTable(Adata, matrix.RowOrder)
	X := matrix.FloatVector([]float64{1.0, 2.0, 3.0, 4.0, 5.0})
	Y := matrix.FloatWithValue(bN, 1, 2.0)

	Ar := A.FloatArray()
	Xr := X.FloatArray()
	Yr := Y.FloatArray()

	blas.GerFloat(X, Y, A0, 1.0)

	DRankMV(Ar, Xr, Yr, 1.0, A.LeadingIndex(), 1, 1, 0, bN, 0, bM, 4, 4)
	ok := A0.AllClose(A)
	t.Logf("A0 == A1: %v\n", ok)
	if !ok {
		t.Logf("blas ger:\n%v\n", A0)
		t.Logf("A1: \n%v\n", A)
	}
}
예제 #2
0
func _TestRank(t *testing.T) {
	bM := M * 100
	bN := N * 100
	//bP := 5

	A := matrix.FloatWithValue(bM, bN, 1.0)
	A0 := matrix.FloatWithValue(bM, bN, 1.0)
	X := matrix.FloatNormal(bM, 1)
	Y := matrix.FloatNormal(bN, 1)

	Ar := A.FloatArray()
	Xr := X.FloatArray()
	Yr := Y.FloatArray()

	blas.GerFloat(X, Y, A0, 1.0)

	DRankMV(Ar, Xr, Yr, 1.0, A.LeadingIndex(), 1, 1, 0, bN, 0, bM, 4, 4)
	t.Logf("GER A0 == A1: %v\n", A0.AllClose(A))
}
예제 #3
0
파일: misc.go 프로젝트: hrautila/cvx
/*
   Applies Nesterov-Todd scaling or its inverse.

   Computes

        x := W*x        (trans is false 'N', inverse = false 'N')
        x := W^T*x      (trans is true  'T', inverse = false 'N')
        x := W^{-1}*x   (trans is false 'N', inverse = true  'T')
        x := W^{-T}*x   (trans is true  'T', inverse = true  'T').

   x is a dense float matrix.

   W is a MatrixSet with entries:

   - W['dnl']: positive vector
   - W['dnli']: componentwise inverse of W['dnl']
   - W['d']: positive vector
   - W['di']: componentwise inverse of W['d']
   - W['v']: lists of 2nd order cone vectors with unit hyperbolic norms
   - W['beta']: list of positive numbers
   - W['r']: list of square matrices
   - W['rti']: list of square matrices.  rti[k] is the inverse transpose
     of r[k].

   The 'dnl' and 'dnli' entries are optional, and only present when the
   function is called from the nonlinear solver.
*/
func scale(x *matrix.FloatMatrix, W *sets.FloatMatrixSet, trans, inverse bool) (err error) {
	/*DEBUGGED*/
	var wl []*matrix.FloatMatrix
	var w *matrix.FloatMatrix
	ind := 0
	err = nil

	// var minor int = 0
	//if ! checkpnt.MinorEmpty() {
	//	minor = checkpnt.MinorTop()
	//}

	//fmt.Printf("\n%d.%04d scaling x=\n%v\n", checkpnt.Major(), minor, x.ToString("%.17f"))

	// Scaling for nonlinear component xk is xk := dnl .* xk; inverse
	// scaling is xk ./ dnl = dnli .* xk, where dnl = W['dnl'],
	// dnli = W['dnli'].

	if wl = W.At("dnl"); wl != nil {
		if inverse {
			w = W.At("dnli")[0]
		} else {
			w = W.At("dnl")[0]
		}
		for k := 0; k < x.Cols(); k++ {
			err = blas.TbmvFloat(w, x, &la_.IOpt{"n", w.Rows()}, &la_.IOpt{"k", 0},
				&la_.IOpt{"lda", 1}, &la_.IOpt{"offsetx", k * x.Rows()})
			if err != nil {
				//fmt.Printf("1. TbmvFloat: %v\n", err)
				return
			}
		}
		ind += w.Rows()
	}

	//if ! checkpnt.MinorEmpty() {
	//    checkpnt.Check("000scale", minor)
	//}

	// Scaling for linear 'l' component xk is xk := d .* xk; inverse
	// scaling is xk ./ d = di .* xk, where d = W['d'], di = W['di'].

	if inverse {
		w = W.At("di")[0]
	} else {
		w = W.At("d")[0]
	}

	for k := 0; k < x.Cols(); k++ {
		err = blas.TbmvFloat(w, x, &la_.IOpt{"n", w.Rows()}, &la_.IOpt{"k", 0},
			&la_.IOpt{"lda", 1}, &la_.IOpt{"offsetx", k*x.Rows() + ind})
		if err != nil {
			//fmt.Printf("2. TbmvFloat: %v\n", err)
			return
		}
	}
	ind += w.Rows()

	//if ! checkpnt.MinorEmpty() {
	//	checkpnt.Check("010scale", minor)
	//}

	// Scaling for 'q' component is
	//
	//    xk := beta * (2*v*v' - J) * xk
	//        = beta * (2*v*(xk'*v)' - J*xk)
	//
	// where beta = W['beta'][k], v = W['v'][k], J = [1, 0; 0, -I].
	//
	//Inverse scaling is
	//
	//    xk := 1/beta * (2*J*v*v'*J - J) * xk
	//        = 1/beta * (-J) * (2*v*((-J*xk)'*v)' + xk).
	//wf := matrix.FloatZeros(x.Cols(), 1)
	w = matrix.FloatZeros(x.Cols(), 1)
	for k, v := range W.At("v") {
		m := v.Rows()
		if inverse {
			blas.ScalFloat(x, -1.0, &la_.IOpt{"offset", ind}, &la_.IOpt{"inc", x.Rows()})
		}
		err = blas.GemvFloat(x, v, w, 1.0, 0.0, la_.OptTrans, &la_.IOpt{"m", m},
			&la_.IOpt{"n", x.Cols()}, &la_.IOpt{"offsetA", ind},
			&la_.IOpt{"lda", x.Rows()})
		if err != nil {
			//fmt.Printf("3. GemvFloat: %v\n", err)
			return
		}

		err = blas.ScalFloat(x, -1.0, &la_.IOpt{"offset", ind}, &la_.IOpt{"inc", x.Rows()})
		if err != nil {
			return
		}

		err = blas.GerFloat(v, w, x, 2.0, &la_.IOpt{"m", m},
			&la_.IOpt{"n", x.Cols()}, &la_.IOpt{"lda", x.Rows()},
			&la_.IOpt{"offsetA", ind})
		if err != nil {
			//fmt.Printf("4. GerFloat: %v\n", err)
			return
		}

		var a float64
		if inverse {
			blas.ScalFloat(x, -1.0,
				&la_.IOpt{"offset", ind}, &la_.IOpt{"inc", x.Rows()})
			// a[i,j] := 1.0/W[i,j]
			a = 1.0 / W.At("beta")[0].GetIndex(k)
		} else {
			a = W.At("beta")[0].GetIndex(k)
		}
		for i := 0; i < x.Cols(); i++ {
			blas.ScalFloat(x, a, &la_.IOpt{"n", m}, &la_.IOpt{"offset", ind + i*x.Rows()})
		}
		ind += m
	}

	//if ! checkpnt.MinorEmpty() {
	//	checkpnt.Check("020scale", minor)
	//}

	// Scaling for 's' component xk is
	//
	//     xk := vec( r' * mat(xk) * r )  if trans = 'N'
	//     xk := vec( r * mat(xk) * r' )  if trans = 'T'.
	//
	// r is kth element of W['r'].
	//
	// Inverse scaling is
	//
	//     xk := vec( rti * mat(xk) * rti' )  if trans = 'N'
	//     xk := vec( rti' * mat(xk) * rti )  if trans = 'T'.
	//
	// rti is kth element of W['rti'].
	maxn := 0
	for _, r := range W.At("r") {
		if r.Rows() > maxn {
			maxn = r.Rows()
		}
	}
	a := matrix.FloatZeros(maxn, maxn)
	for k, v := range W.At("r") {
		t := trans
		var r *matrix.FloatMatrix
		if !inverse {
			r = v
			t = !trans
		} else {
			r = W.At("rti")[k]
		}

		n := r.Rows()
		for i := 0; i < x.Cols(); i++ {
			// scale diagonal of xk by 0.5
			blas.ScalFloat(x, 0.5, &la_.IOpt{"offset", ind + i*x.Rows()},
				&la_.IOpt{"inc", n + 1}, &la_.IOpt{"n", n})

			// a = r*tril(x) (t is 'N') or a = tril(x)*r  (t is 'T')
			blas.Copy(r, a)
			if !t {
				err = blas.TrmmFloat(x, a, 1.0, la_.OptRight, &la_.IOpt{"m", n},
					&la_.IOpt{"n", n}, &la_.IOpt{"lda", n}, &la_.IOpt{"ldb", n},
					&la_.IOpt{"offsetA", ind + i*x.Rows()})
				if err != nil {
					//fmt.Printf("5. TrmmFloat: %v\n", err)
					return
				}

				// x := (r*a' + a*r')  if t is 'N'
				err = blas.Syr2kFloat(r, a, x, 1.0, 0.0, la_.OptNoTrans, &la_.IOpt{"n", n},
					&la_.IOpt{"k", n}, &la_.IOpt{"ldb", n}, &la_.IOpt{"ldc", n},
					&la_.IOpt{"offsetC", ind + i*x.Rows()})
				if err != nil {
					//fmt.Printf("6. Syr2kFloat: %v\n", err)
					return
				}

			} else {
				err = blas.TrmmFloat(x, a, 1.0, la_.OptLeft, &la_.IOpt{"m", n},
					&la_.IOpt{"n", n}, &la_.IOpt{"lda", n}, &la_.IOpt{"ldb", n},
					&la_.IOpt{"offsetA", ind + i*x.Rows()})
				if err != nil {
					//fmt.Printf("7. TrmmFloat: %v\n", err)
					return
				}

				// x := (r'*a + a'*r)  if t is 'T'
				err = blas.Syr2kFloat(r, a, x, 1.0, 0.0, la_.OptTrans, &la_.IOpt{"n", n},
					&la_.IOpt{"k", n}, &la_.IOpt{"ldb", n}, &la_.IOpt{"ldc", n},
					&la_.IOpt{"offsetC", ind + i*x.Rows()})
				if err != nil {
					//fmt.Printf("8. Syr2kFloat: %v\n", err)
					return
				}
			}
		}
		ind += n * n
	}
	//if ! checkpnt.MinorEmpty() {
	//	checkpnt.Check("030scale", minor)
	//}
	return
}