// MeanBatch predicts the mean at the set of locations specified by x. Stores in-place into yPred // If yPred is nil new memory is allocated. func (g *GP) MeanBatch(yPred []float64, x mat64.Matrix) []float64 { rx, cx := x.Dims() if cx != g.inputDim { panic(badInputLength) } if yPred == nil { yPred = make([]float64, rx) } ry := len(yPred) if rx != ry { panic(badOutputLength) } nSamples, _ := g.inputs.Dims() covariance := mat64.NewDense(nSamples, rx, nil) row := make([]float64, g.inputDim) for j := 0; j < rx; j++ { for k := 0; k < g.inputDim; k++ { row[k] = x.At(j, k) } for i := 0; i < nSamples; i++ { v := g.kernel.Distance(g.inputs.RawRowView(i), row) covariance.Set(i, j, v) } } yPredVec := mat64.NewVector(len(yPred), yPred) yPredVec.MulVec(covariance.T(), g.sigInvY) // Rescale the outputs for i, v := range yPred { yPred[i] = v*g.std + g.mean } return yPred }
func MatrixToImage(src mat64.Matrix) image.Image { width, height := src.Dims() img := image.NewRGBA(image.Rect(0, 0, width, height)) for x := 0; x < width; x++ { for y := 0; y < height; y++ { img.Set(x, y, Float64ToColor(src.At(x, y))) } } return img }
func verifyInputs(initialBasic []int, c []float64, A mat64.Matrix, b []float64) error { m, n := A.Dims() if len(c) != n { panic("lp: c vector incorrect length") } if len(b) != m { panic("lp: b vector incorrect length") } if len(c) != n { panic("lp: c vector incorrect length") } if len(initialBasic) != 0 && len(initialBasic) != m { panic("lp: initialBasic incorrect length") } // Do some sanity checks so that ab does not become singular during the // simplex solution. If the ZeroRow checks are removed then the code for // finding a set of linearly indepent columns must be improved. // Check that if a row of A only has zero elements that corresponding // element in b is zero, otherwise the problem is infeasible. // Otherwise return ErrZeroRow. for i := 0; i < m; i++ { isZero := true for j := 0; j < n; j++ { if A.At(i, j) != 0 { isZero = false break } } if isZero && b[i] != 0 { // Infeasible return ErrInfeasible } else if isZero { return ErrZeroRow } } // Check that if a column only has zero elements that the respective C vector // is positive (otherwise unbounded). Otherwise return ErrZeroColumn. for j := 0; j < n; j++ { isZero := true for i := 0; i < m; i++ { if A.At(i, j) != 0 { isZero = false break } } if isZero && c[j] < 0 { return ErrUnbounded } else if isZero { return ErrZeroColumn } } return nil }
func CropMatrix(src mat64.Matrix, x0, y0, x1, y1 int) (*mat64.Dense, error) { rows := y1 - y0 + 1 cols := x1 - x0 + 1 mtx := make([]float64, rows*cols) for x := x0; x <= x1; x++ { for y := y0; y <= y1; y++ { mtx[(y-y0)*cols+(x-x0)] = src.At(x, y) } } return mat64.NewDense(rows, cols, mtx), nil }
func transpose(A mat64.Matrix) mat64.Matrix { r, s := A.Dims() var data []float64 for j := 0; j < s; j++ { for i := 0; i < r; i++ { data = append(data, A.At(i, j)) } } // Está medio chafa que regrese Dense, cómo hacemos para que regrese // el mismo tipo de A? return mat64.NewDense(s, r, data) }
// PrintMat imprime una matriz con un formato entendible func PrintMat(A mat64.Matrix) { r, s := A.Dims() fmt.Printf("(") for i := 0; i < r; i++ { fmt.Printf("\t") for j := 0; j < s; j++ { fmt.Printf("%0.1f\t", A.At(i, j)) } if i != r-1 { fmt.Printf("\n") } } fmt.Printf(")\n") }
// formKStar forms the covariance matrix between the inputs and new points. func (g *GP) formKStar(x mat64.Matrix) *mat64.Dense { // TODO(btracey): Parallelize r, c := x.Dims() n := len(g.outputs) kStar := mat64.NewDense(n, r, nil) data := make([]float64, c) for j := 0; j < r; j++ { for k := 0; k < c; k++ { data[k] = x.At(j, k) } for i := 0; i < n; i++ { row := g.inputs.RawRowView(i) v := g.kernel.Distance(row, data) kStar.Set(i, j, v) } } return kStar }
// StdDevBatch predicts the standard deviation at a set of locations of x. func (g *GP) StdDevBatch(std []float64, x mat64.Matrix) []float64 { r, c := x.Dims() if c != g.inputDim { panic(badInputLength) } if std == nil { std = make([]float64, r) } if len(std) != r { panic(badStorage) } // For a single point, the stddev is // sigma = k(x,x) - k_*^T * K^-1 * k_* // where k is the vector of kernels between the input points and the output points // For many points, the formula is: // nu_* = k(x_*, k_*) - k_*^T * K^-1 * k_* // This creates the full covariance matrix which is an rxr matrix. However, // the standard deviations are just the diagonal of this matrix. Instead, be // smart about it and compute the diagonal terms one at a time. kStar := g.formKStar(x) var tmp mat64.Dense tmp.SolveCholesky(g.cholK, kStar) // set k(x_*, x_*) into std then subtract k_*^T K^-1 k_* , computed one row at a time var tmp2 mat64.Vector row := make([]float64, c) for i := range std { for k := 0; k < c; k++ { row[k] = x.At(i, k) } std[i] = g.kernel.Distance(row, row) tmp2.MulVec(kStar.ColView(i).T(), tmp.ColView(i)) rt, ct := tmp2.Dims() if rt != 1 && ct != 1 { panic("bad size") } std[i] -= tmp2.At(0, 0) std[i] = math.Sqrt(std[i]) } // Need to scale the standard deviation to be in the same units as y. floats.Scale(g.std, std) return std }
//This is a temporal function. It returns the determinant of a 3x3 matrix. Panics if the matrix is not 3x3. //It is also defined in the chem package which is not-so-clean. func det(A mat64.Matrix) float64 { r, c := A.Dims() if r != 3 || c != 3 { panic(ErrDeterminant) } return (A.At(0, 0)*(A.At(1, 1)*A.At(2, 2)-A.At(2, 1)*A.At(1, 2)) - A.At(1, 0)*(A.At(0, 1)*A.At(2, 2)-A.At(2, 1)*A.At(0, 2)) + A.At(2, 0)*(A.At(0, 1)*A.At(1, 2)-A.At(1, 1)*A.At(0, 2))) }