/* Copy x to y using packed storage. The vector x is an element of S, with the 's' components stored in unpacked storage. On return, x is copied to y with the 's' components stored in packed storage and the off-diagonal entries scaled by sqrt(2). */ func pack(x, y *matrix.FloatMatrix, dims *DimensionSet, opts ...la_.Option) (err error) { /*DEBUGGED*/ err = nil mnl := la_.GetIntOpt("mnl", 0, opts...) offsetx := la_.GetIntOpt("offsetx", 0, opts...) offsety := la_.GetIntOpt("offsety", 0, opts...) nlq := mnl + dims.At("l")[0] + dims.Sum("q") blas.Copy(x, y, &la_.IOpt{"n", nlq}, &la_.IOpt{"offsetx", offsetx}, &la_.IOpt{"offsety", offsety}) iu, ip := offsetx+nlq, offsety+nlq for _, n := range dims.At("s") { for k := 0; k < n; k++ { blas.Copy(x, y, &la_.IOpt{"n", n - k}, &la_.IOpt{"offsetx", iu + k*(n+1)}, &la_.IOpt{"offsety", ip}) y.SetIndex(ip, (y.GetIndex(ip) / math.Sqrt(2.0))) ip += n - k } iu += n * n } np := dims.SumPacked("s") blas.ScalFloat(y, math.Sqrt(2.0), &la_.IOpt{"n", np}, &la_.IOpt{"offset", offsety + nlq}) return }
/* Matrix-vector multiplication. A is a matrix or spmatrix of size (m, n) where N = dims['l'] + sum(dims['q']) + sum( k**2 for k in dims['s'] ) representing a mapping from R^n to S. If trans is 'N': y := alpha*A*x + beta * y (trans = 'N'). x is a vector of length n. y is a vector of length N. If trans is 'T': y := alpha*A'*x + beta * y (trans = 'T'). x is a vector of length N. y is a vector of length n. The 's' components in S are stored in unpacked 'L' storage. */ func sgemv(A, x, y *matrix.FloatMatrix, alpha, beta float64, dims *DimensionSet, opts ...la_.Option) error { m := dims.Sum("l", "q") + dims.SumSquared("s") n := la_.GetIntOpt("n", -1, opts...) if n == -1 { n = A.Cols() } trans := la_.GetIntOpt("trans", int(la_.PNoTrans), opts...) offsetX := la_.GetIntOpt("offsetx", 0, opts...) offsetY := la_.GetIntOpt("offsety", 0, opts...) offsetA := la_.GetIntOpt("offseta", 0, opts...) if trans == int(la_.PTrans) && alpha != 0.0 { trisc(x, dims, offsetX) //fmt.Printf("trisc x=\n%v\n", x.ConvertToString()) } //fmt.Printf("alpha=%.4f beta=%.4f m=%d n=%d\n", alpha, beta, m, n) //fmt.Printf("A=\n%v\nx=\n%v\ny=\n%v\n", A, x.ConvertToString(), y.ConvertToString()) err := blas.GemvFloat(A, x, y, alpha, beta, &la_.IOpt{"trans", trans}, &la_.IOpt{"n", n}, &la_.IOpt{"m", m}, &la_.IOpt{"offseta", offsetA}, &la_.IOpt{"offsetx", offsetX}, &la_.IOpt{"offsety", offsetY}) //fmt.Printf("gemv y=\n%v\n", y.ConvertToString()) if trans == int(la_.PTrans) && alpha != 0.0 { triusc(x, dims, offsetX) } return err }
func doScale(G *matrix.FloatMatrix, W *cvx.FloatMatrixSet) { g := matrix.FloatZeros(G.Rows(), 1) g.SetIndexes(matrix.MakeIndexSet(0, g.Rows(), 1), G.GetColumn(0, nil)) fmt.Printf("** scaling g:\n%v\n", g) cvx.Scale(g, W, true, true) fmt.Printf("== scaled g:\n%v\n", g) }
// See function Syrk. func SyrkFloat(A, C *matrix.FloatMatrix, alpha, beta float64, opts ...linalg.Option) (err error) { params, e := linalg.GetParameters(opts...) if e != nil { err = e return } ind := linalg.GetIndexOpts(opts...) err = check_level3_func(ind, fsyrk, A, nil, C, params) if e != nil || err != nil { return } if ind.N == 0 { return } Aa := A.FloatArray() Ca := C.FloatArray() uplo := linalg.ParamString(params.Uplo) trans := linalg.ParamString(params.Trans) //diag := linalg.ParamString(params.Diag) dsyrk(uplo, trans, ind.N, ind.K, alpha, Aa[ind.OffsetA:], ind.LDa, beta, Ca[ind.OffsetC:], ind.LDc) return }
// See function Trsm. func TrsmFloat(A, B *matrix.FloatMatrix, alpha float64, opts ...linalg.Option) (err error) { params, e := linalg.GetParameters(opts...) if e != nil { err = e return } ind := linalg.GetIndexOpts(opts...) err = check_level3_func(ind, ftrsm, A, B, nil, params) if err != nil { return } if ind.N == 0 || ind.M == 0 { return } Aa := A.FloatArray() Ba := B.FloatArray() uplo := linalg.ParamString(params.Uplo) transA := linalg.ParamString(params.TransA) side := linalg.ParamString(params.Side) diag := linalg.ParamString(params.Diag) dtrsm(side, uplo, transA, diag, ind.M, ind.N, alpha, Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb) return }
func GbtrsFloat(A, B *matrix.FloatMatrix, ipiv []int32, KL int, opts ...linalg.Option) error { pars, err := linalg.GetParameters(opts...) if err != nil { return err } ind := linalg.GetIndexOpts(opts...) ind.Kl = KL err = checkGbtrs(ind, A, B, ipiv) if err != nil { return err } if ind.N == 0 || ind.Nrhs == 0 { return nil } Aa := A.FloatArray() Ba := B.FloatArray() trans := linalg.ParamString(pars.Trans) info := dgbtrs(trans, ind.N, ind.Kl, ind.Ku, ind.Nrhs, Aa[ind.OffsetA:], ind.LDa, ipiv, Ba[ind.OffsetB:], ind.LDb) if info != 0 { return errors.New(fmt.Sprintf("Gbtrs: call error: %d", info)) } return nil }
func setDiagonal(M *matrix.FloatMatrix, srow, scol, erow, ecol int, val float64) { for i := srow; i < erow; i++ { if i < ecol { M.SetAt(i, i, val) } } }
func matrixNaN(x *matrix.FloatMatrix) bool { for i := 0; i < x.NumElements(); i++ { if math.IsNaN(x.GetIndex(i)) { return true } } return false }
func (p *FloorPlan) F2(x, z *matrix.FloatMatrix) (f, Df, H *matrix.FloatMatrix, err error) { f, Df, err = p.F1(x) x17 := matrix.FloatVector(x.FloatArray()[17:]) tmp := p.Amin.Div(x17.Pow(3.0)) tmp = z.Mul(tmp).Scale(2.0) diag := matrix.FloatDiagonal(5, tmp.FloatArray()...) H = matrix.FloatZeros(22, 22) H.SetSubMatrix(17, 17, diag) return }
func sinv(x, y *matrix.FloatMatrix, dims *DimensionSet, mnl int) (err error) { /*DEBUGGED*/ err = nil // For the nonlinear and 'l' blocks: // // yk o\ xk = yk .\ xk. ind := mnl + dims.At("l")[0] blas.Tbsv(y, x, &la_.IOpt{"n", ind}, &la_.IOpt{"k", 0}, &la_.IOpt{"ldA", 1}) // For the 'q' blocks: // // [ l0 -l1' ] // yk o\ xk = 1/a^2 * [ ] * xk // [ -l1 (a*I + l1*l1')/l0 ] // // where yk = (l0, l1) and a = l0^2 - l1'*l1. for _, m := range dims.At("q") { aa := blas.Nrm2Float(y, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offset", ind + 1}) ee := y.GetIndex(ind) aa = (ee + aa) * (ee - aa) cc := x.GetIndex(ind) dd := blas.DotFloat(x, y, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offsetx", ind + 1}, &la_.IOpt{"offsety", ind + 1}) x.SetIndex(ind, cc*ee-dd) blas.ScalFloat(x, aa/ee, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offset", ind + 1}) blas.AxpyFloat(y, x, dd/ee-cc, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offsetx", ind + 1}, &la_.IOpt{"offsety", ind + 1}) blas.ScalFloat(x, 1.0/aa, &la_.IOpt{"n", m}, &la_.IOpt{"offset", ind}) ind += m } // For the 's' blocks: // // yk o\ xk = xk ./ gamma // // where gammaij = .5 * (yk_i + yk_j). ind2 := ind for _, m := range dims.At("s") { for j := 0; j < m; j++ { u := matrix.FloatVector(y.FloatArray()[ind2+j : ind2+m]) u.Add(y.GetIndex(ind2 + j)) u.Scale(0.5) blas.Tbsv(u, x, &la_.IOpt{"n", m - j}, &la_.IOpt{"k", 0}, &la_.IOpt{"lda", 1}, &la_.IOpt{"offsetx", ind + j*(m+1)}) } ind += m * m ind2 += m } return }
/* 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) }
// See function Scal. func ScalFloat(X *matrix.FloatMatrix, alpha float64, opts ...linalg.Option) (err error) { ind := linalg.GetIndexOpts(opts...) err = check_level1_func(ind, fscal, X, nil) if err != nil { return } if ind.Nx == 0 { return } Xa := X.FloatArray() dscal(ind.Nx, alpha, Xa[ind.OffsetX:], ind.IncX) return }
func GesvdFloat(A, S, U, Vt *matrix.FloatMatrix, opts ...linalg.Option) error { pars, err := linalg.GetParameters(opts...) if err != nil { return err } ind := linalg.GetIndexOpts(opts...) err = checkGesvd(ind, pars, A, S, U, Vt) if err != nil { return err } if ind.M == 0 || ind.N == 0 { return nil } Aa := A.FloatArray() Sa := S.FloatArray() var Ua, Va []float64 Ua = nil Va = nil if U != nil { Ua = U.FloatArray()[ind.OffsetU:] } if Vt != nil { Va = Vt.FloatArray()[ind.OffsetVt:] } info := dgesvd(linalg.ParamString(pars.Jobu), linalg.ParamString(pars.Jobvt), ind.M, ind.N, Aa[ind.OffsetA:], ind.LDa, Sa[ind.OffsetS:], Ua, ind.LDu, Va, ind.LDvt) if info != 0 { return errors.New("GesvdFloat not implemented yet") } return nil }
// See function Copy. func CopyFloat(X, Y *matrix.FloatMatrix, opts ...linalg.Option) (err error) { ind := linalg.GetIndexOpts(opts...) err = check_level1_func(ind, fcopy, X, Y) if err != nil { return } if ind.Nx == 0 { return } Xa := X.FloatArray() Ya := Y.FloatArray() dcopy(ind.Nx, Xa[ind.OffsetX:], ind.IncX, Ya[ind.OffsetY:], ind.IncY) return }
// See function Asum. func AsumFloat(X *matrix.FloatMatrix, opts ...linalg.Option) (v float64) { v = math.NaN() ind := linalg.GetIndexOpts(opts...) err := check_level1_func(ind, fasum, X, nil) if err != nil { return } if ind.Nx == 0 { v = 0.0 return } Xa := X.FloatArray() v = dasum(ind.Nx, Xa[ind.OffsetX:], ind.IncX) return }
// not really needed. func createLdlSolver(G *matrix.FloatMatrix, dims *DimensionSet, A *matrix.FloatMatrix, mnl int) *kktLdlSolver { kkt := new(kktLdlSolver) kkt.p, kkt.n = A.Size() kkt.ldK = kkt.n + kkt.p + mnl + dims.Sum("l", "q") + dims.SumPacked("s") kkt.K = matrix.FloatZeros(kkt.ldK, kkt.ldK) kkt.ipiv = make([]int32, kkt.ldK) kkt.u = matrix.FloatZeros(kkt.ldK, 1) kkt.g = matrix.FloatZeros(kkt.mnl+G.Rows(), 1) kkt.G = G kkt.A = A kkt.dims = dims kkt.mnl = mnl return kkt }
// See functin Dot. func DotFloat(X, Y *matrix.FloatMatrix, opts ...linalg.Option) (v float64) { v = math.NaN() ind := linalg.GetIndexOpts(opts...) err := check_level1_func(ind, fdot, X, Y) if err != nil { return } if ind.Nx == 0 { v = 0.0 return } Xa := X.FloatArray() Ya := Y.FloatArray() v = ddot(ind.Nx, Xa[ind.OffsetX:], ind.IncX, Ya[ind.OffsetY:], ind.IncY) return }
// Returns min {t | x + t*e >= 0}, where e is defined as follows // // - For the nonlinear and 'l' blocks: e is the vector of ones. // - For the 'q' blocks: e is the first unit vector. // - For the 's' blocks: e is the identity matrix. // // When called with the argument sigma, also returns the eigenvalues // (in sigma) and the eigenvectors (in x) of the 's' components of x. func maxStep(x *matrix.FloatMatrix, dims *DimensionSet, mnl int, sigma *matrix.FloatMatrix) (rval float64, err error) { /*DEBUGGED*/ rval = 0.0 err = nil t := make([]float64, 0, 10) ind := mnl + dims.Sum("l") if ind > 0 { t = append(t, -minvec(x.FloatArray()[:ind])) } for _, m := range dims.At("q") { if m > 0 { v := blas.Nrm2Float(x, &la_.IOpt{"offset", ind + 1}, &la_.IOpt{"n", m - 1}) v -= x.GetIndex(ind) t = append(t, v) } ind += m } var Q *matrix.FloatMatrix var w *matrix.FloatMatrix ind2 := 0 if sigma == nil && len(dims.At("s")) > 0 { mx := dims.Max("s") Q = matrix.FloatZeros(mx, mx) w = matrix.FloatZeros(mx, 1) } for _, m := range dims.At("s") { if sigma == nil { blas.Copy(x, Q, &la_.IOpt{"offsetx", ind}, &la_.IOpt{"n", m * m}) err = lapack.SyevrFloat(Q, w, nil, 0.0, nil, []int{1, 1}, la_.OptRangeInt, &la_.IOpt{"n", m}, &la_.IOpt{"lda", m}) if m > 0 { t = append(t, -w.GetIndex(0)) } } else { err = lapack.SyevdFloat(x, sigma, la_.OptJobZValue, &la_.IOpt{"n", m}, &la_.IOpt{"lda", m}, &la_.IOpt{"offseta", ind}, &la_.IOpt{"offsetw", ind2}) if m > 0 { t = append(t, -sigma.GetIndex(ind2)) } } ind += m * m ind2 += m } if len(t) > 0 { rval = maxvec(t) } return }
func GbtrfFloat(A *matrix.FloatMatrix, ipiv []int32, M, KL int, opts ...linalg.Option) error { ind := linalg.GetIndexOpts(opts...) ind.M = M ind.Kl = KL err := checkGbtrf(ind, A, ipiv) if err != nil { return err } if ind.M == 0 || ind.N == 0 { return nil } Aa := A.FloatArray() info := dgbtrf(ind.M, ind.N, ind.Kl, ind.Ku, Aa[ind.OffsetA:], ind.LDa, ipiv) if info != 0 { return errors.New(fmt.Sprintf("Gbtrf call error: %d", info)) } return nil }
func PotrfFloat(A *matrix.FloatMatrix, opts ...linalg.Option) error { pars, err := linalg.GetParameters(opts...) if err != nil { return err } ind := linalg.GetIndexOpts(opts...) err = checkPotrf(ind, A) if ind.N == 0 { return nil } Aa := A.FloatArray() uplo := linalg.ParamString(pars.Uplo) info := dpotrf(uplo, ind.N, Aa[ind.OffsetA:], ind.LDa) if info != 0 { return errors.New(fmt.Sprintf("Potrf: call error %d", info)) } return nil }
// The product x := y o y. The 's' components of y are diagonal and // only the diagonals of x and y are stored. func ssqr(x, y *matrix.FloatMatrix, dims *DimensionSet, mnl int) (err error) { /*DEBUGGED*/ blas.Copy(y, x) ind := mnl + dims.At("l")[0] err = blas.Tbmv(y, x, &la_.IOpt{"n", ind}, &la_.IOpt{"k", 0}, &la_.IOpt{"lda", 1}) if err != nil { return } for _, m := range dims.At("q") { v := blas.Nrm2Float(y, &la_.IOpt{"n", m}, &la_.IOpt{"offset", ind}) x.SetIndex(ind, v*v) blas.ScalFloat(x, 2.0*y.GetIndex(ind), &la_.IOpt{"n", m - 1}, &la_.IOpt{"offset", ind + 1}) ind += m } err = blas.Tbmv(y, x, &la_.IOpt{"n", dims.Sum("s")}, &la_.IOpt{"k", 0}, &la_.IOpt{"lda", 1}, &la_.IOpt{"offseta", ind}, &la_.IOpt{"offsetx", ind}) return }
// See function Syr. func SyrFloat(X, A *matrix.FloatMatrix, alpha float64, opts ...linalg.Option) (err error) { var params *linalg.Parameters params, err = linalg.GetParameters(opts...) if err != nil { return } ind := linalg.GetIndexOpts(opts...) err = check_level2_func(ind, fsyr, X, nil, A, params) if err != nil { return } if ind.N == 0 { return } Xa := X.FloatArray() Aa := A.FloatArray() uplo := linalg.ParamString(params.Uplo) dsyr(uplo, ind.N, alpha, Xa[ind.OffsetX:], ind.IncX, Aa[ind.OffsetA:], ind.LDa) return }
func GbsvFloat(A, B *matrix.FloatMatrix, ipiv []int32, kl int, opts ...linalg.Option) error { ind := linalg.GetIndexOpts(opts...) ind.Kl = kl err := checkGbsv(ind, A, B, ipiv) if err != nil { return err } if ind.N == 0 || ind.Nrhs == 0 { return nil } Aa := A.FloatArray() Ba := B.FloatArray() info := dgbsv(ind.N, ind.Kl, ind.Ku, ind.Nrhs, Aa[ind.OffsetA:], ind.LDa, ipiv, Ba[ind.OffsetB:], ind.LDb) if info != 0 { return errors.New(fmt.Sprintf("Gbsv call error: %d", info)) } return nil }
// See function Gbmv. func GbmvFloat(A, X, Y *matrix.FloatMatrix, alpha, beta float64, opts ...linalg.Option) (err error) { var params *linalg.Parameters params, err = linalg.GetParameters(opts...) if err != nil { return } ind := linalg.GetIndexOpts(opts...) err = check_level2_func(ind, fgbmv, X, Y, A, params) if err != nil { return } if ind.M == 0 && ind.N == 0 { return } Xa := X.FloatArray() Ya := Y.FloatArray() Aa := A.FloatArray() if params.Trans == linalg.PNoTrans && ind.N == 0 { dscal(ind.M, beta, Ya[ind.OffsetY:], ind.IncY) } else if params.Trans == linalg.PTrans && ind.M == 0 { dscal(ind.N, beta, Ya[ind.OffsetY:], ind.IncY) } else { trans := linalg.ParamString(params.Trans) dgbmv(trans, ind.M, ind.N, ind.Kl, ind.Ku, alpha, Aa[ind.OffsetA:], ind.LDa, Xa[ind.OffsetX:], ind.IncX, beta, Ya[ind.OffsetY:], ind.IncY) } return }
// See function Symm. func SymmFloat(A, B, C *matrix.FloatMatrix, alpha, beta float64, opts ...linalg.Option) (err error) { params, e := linalg.GetParameters(opts...) if e != nil { err = e return } ind := linalg.GetIndexOpts(opts...) err = check_level3_func(ind, fsymm, A, B, C, params) if err != nil { return } if ind.M == 0 || ind.N == 0 { return } Aa := A.FloatArray() Ba := B.FloatArray() Ca := C.FloatArray() uplo := linalg.ParamString(params.Uplo) side := linalg.ParamString(params.Side) dsymm(side, uplo, ind.M, ind.N, alpha, Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb, beta, Ca[ind.OffsetC:], ind.LDc) return }
// See function Gemm. func GemmFloat(A, B, C *matrix.FloatMatrix, alpha, beta float64, opts ...linalg.Option) (err error) { params, e := linalg.GetParameters(opts...) if e != nil { err = e return } ind := linalg.GetIndexOpts(opts...) err = check_level3_func(ind, fgemm, A, B, C, params) if err != nil { return } if ind.M == 0 || ind.N == 0 { return } Aa := A.FloatArray() Ba := B.FloatArray() Ca := C.FloatArray() transB := linalg.ParamString(params.TransB) transA := linalg.ParamString(params.TransA) //diag := linalg.ParamString(params.Diag) dgemm(transA, transB, ind.M, ind.N, ind.K, alpha, Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb, beta, Ca[ind.OffsetC:], ind.LDc) return }
/* 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 }
func SyevdFloat(A, W *matrix.FloatMatrix, opts ...linalg.Option) error { pars, err := linalg.GetParameters(opts...) if err != nil { return err } ind := linalg.GetIndexOpts(opts...) err = checkSyevd(ind, A, W) if err != nil { return err } if ind.N == 0 { return nil } jobz := linalg.ParamString(pars.Jobz) uplo := linalg.ParamString(pars.Uplo) Aa := A.FloatArray() Wa := W.FloatArray() info := dsyevd(jobz, uplo, ind.N, Aa[ind.OffsetA:], ind.LDa, Wa[ind.OffsetW:]) if info != 0 { return errors.New(fmt.Sprintf("Syevd: call error %d", info)) } return nil }
// See function Tbsv. func TbsvFloat(A, X *matrix.FloatMatrix, opts ...linalg.Option) (err error) { var params *linalg.Parameters params, err = linalg.GetParameters(opts...) if err != nil { return } ind := linalg.GetIndexOpts(opts...) err = check_level2_func(ind, ftbsv, X, nil, A, params) if err != nil { return } if ind.N == 0 { return } Xa := X.FloatArray() Aa := A.FloatArray() uplo := linalg.ParamString(params.Uplo) trans := linalg.ParamString(params.Trans) diag := linalg.ParamString(params.Diag) dtbsv(uplo, trans, diag, ind.N, ind.K, Aa[ind.OffsetA:], ind.LDa, Xa[ind.OffsetX:], ind.IncX) return }
func (p *FloorPlan) F1(x *matrix.FloatMatrix) (f, Df *matrix.FloatMatrix, err error) { err = nil mn := x.Min(-1, -2, -3, -4, -5) if mn <= 0.0 { f, Df = nil, nil return } zeros := matrix.FloatZeros(5, 12) dk1 := matrix.FloatDiagonal(5, -1.0) dk2 := matrix.FloatZeros(5, 5) x17 := matrix.FloatVector(x.FloatArray()[17:]) // -( Amin ./ (x17 .* x17) ) diag := p.Amin.Div(x17.Mul(x17)).Scale(-1.0) dk2.SetIndexes(matrix.MakeDiagonalSet(5, 5), diag.FloatArray()) Df, _ = matrix.FloatMatrixCombined(matrix.StackRight, zeros, dk1, dk2) x12 := matrix.FloatVector(x.FloatArray()[12:17]) // f = -x[12:17] + div(Amin, x[17:]) f = p.Amin.Div(x17).Minus(x12) return }