// Calculates the variance-covariance matrix of the regression coefficients // defined as sigma*(XtX)-1 // Using QR decomposition: X = QR // ((QR)tQR)-1 ---> (RtQtQR)-1 ---> (RtR)-1 ---> R-1Rt-1 --> sigma*R-1Rt-1 // func (o *OLS) VarianceCovarianceMatrix() *mat64.Dense { x := mat64.DenseCopyOf(o.x.data) _, p := x.Dims() // it's easier to do things with X = QR qrFactor := mat64.QR(x) R := qrFactor.R() Rt := R.T() RtInv, err := mat64.Inverse(Rt) if err != nil { panic("Rt is not invertible") } Rinverse, err := mat64.Inverse(R) if err != nil { panic("R matrix is not invertible") } varCov := mat64.NewDense(p, p, nil) varCov.Mul(Rinverse, RtInv) // multiple each element by the mse mse := o.MeanSquaredError() mulEach := func(r, c int, v float64) float64 { return v * mse } varCov.Apply(mulEach, varCov) return varCov }
// Nearest returns the nearest grid point to p by rounding each dimensional // position to the nearest grid point. If the mesh basis is not the identity // matrix, then p is transformed to the mesh basis before rounding and then // retransformed back. func (m *InfMesh) Nearest(p []float64) []float64 { if m.StepSize == 0 { return append([]float64{}, p...) } else if l := len(m.Center); l != 0 && l != len(p) { panic(fmt.Sprintf("origin len %v incompatible with point len %v", l, len(p))) } // set up origin and inverter matrix if necessary if len(m.Center) == 0 { m.Center = make([]float64, len(p)) } if m.Basis != nil && m.inverter == nil { var err error m.inverter, err = mat64.Inverse(m.Basis) if err != nil { panic("basis inversion failed: " + err.Error()) } } // translate p based on origin and transform to new vector space newp := make([]float64, len(p)) for i := range newp { newp[i] = p[i] - m.Center[i] } v := mat64.NewDense(len(m.Center), 1, newp) rotv := v if m.inverter != nil { rotv.Mul(m.inverter, v) } // calculate nearest point nearest := mat64.NewDense(len(p), 1, nil) for i := range m.Center { n, rem := math.Modf(rotv.At(i, 0) / m.StepSize) if rem/m.StepSize > 0.5 { n++ } nearest.Set(i, 0, float64(n)*m.StepSize) } // transform back to standard space if m.Basis != nil { nearest.Mul(m.Basis, nearest) } nv := nearest.Col(nil, 0) for i := range nv { nv[i] += m.Center[i] } return nv }