// onesDotUnitary performs the equivalent of a Ddot of v with // a ones vector of equal length. v must have have a unitary // vector increment. func onesDotUnitary(alpha float64, v *mat64.Vector) float64 { var sum float64 for _, f := range v.RawVector().Data { sum += alpha * f } return sum }
func dokMulMatVec(y *mat64.Vector, alpha float64, transA bool, a *DOK, x *mat64.Vector) { r, c := a.Dims() if transA { if r != x.Len() || c != y.Len() { panic("sparse: dimension mismatch") } } else { if r != y.Len() || c != x.Len() { panic("sparse: dimension mismatch") } } if alpha == 0 { return } xRaw := x.RawVector() yRaw := y.RawVector() if transA { for ij, aij := range a.data { yRaw.Data[ij[1]*yRaw.Inc] += alpha * aij * xRaw.Data[ij[0]*xRaw.Inc] } } else { for ij, aij := range a.data { yRaw.Data[ij[0]*yRaw.Inc] += alpha * aij * xRaw.Data[ij[1]*xRaw.Inc] } } }
// dotUnitary performs a simplified scatter-based Ddot operations on // v and the receiver. v must have have a unitary vector increment. func (r compressedRow) dotUnitary(v *mat64.Vector) float64 { var sum float64 vec := v.RawVector().Data for _, e := range r { sum += vec[e.index] * e.value } return sum }
// Scatter copies the values of x into the corresponding locations in the dense // vector y. Both vectors must have the same dimension. func Scatter(y *mat64.Vector, x *Vector) { if x.N != y.Len() { panic("sparse: vector dimension mismatch") } raw := y.RawVector() for i, index := range x.Indices { raw.Data[index*raw.Inc] = x.Data[i] } }
// Dot computes the dot product of the sparse vector x with the dense vector y. // The vectors must have the same dimension. func Dot(x *Vector, y *mat64.Vector) (dot float64) { if x.N != y.Len() { panic("sparse: vector dimension mismatch") } raw := y.RawVector() for i, index := range x.Indices { dot += x.Data[i] * raw.Data[index*raw.Inc] } return }
// Gather gathers entries given by indices of the dense vector y into the sparse // vector x. Indices must not be nil. func Gather(x *Vector, y *mat64.Vector, indices []int) { if indices == nil { panic("sparse: slice is nil") } x.reuseAs(y.Len(), len(indices)) copy(x.Indices, indices) raw := y.RawVector() for i, index := range x.Indices { x.Data[i] = raw.Data[index*raw.Inc] } }
// Axpy scales the sparse vector x by alpha and adds the result to the dense // vector y. If alpha is zero, y is not modified. func Axpy(y *mat64.Vector, alpha float64, x *Vector) { if x.N != y.Len() { panic("sparse: vector dimension mismatch") } if alpha == 0 { return } raw := y.RawVector() for i, index := range x.Indices { raw.Data[index*raw.Inc] += alpha * x.Data[i] } }
func csrMulMatVec(y *mat64.Vector, alpha float64, transA bool, a *CSR, x *mat64.Vector) { r, c := a.Dims() if transA { if r != x.Len() || c != y.Len() { panic("sparse: dimension mismatch") } } else { if r != y.Len() || c != x.Len() { panic("sparse: dimension mismatch") } } if alpha == 0 { return } yRaw := y.RawVector() if transA { row := Vector{N: y.Len()} for i := 0; i < r; i++ { start := a.rowIndex[i] end := a.rowIndex[i+1] row.Data = a.values[start:end] row.Indices = a.columns[start:end] Axpy(y, alpha*x.At(i, 0), &row) } } else { row := Vector{N: x.Len()} for i := 0; i < r; i++ { start := a.rowIndex[i] end := a.rowIndex[i+1] row.Data = a.values[start:end] row.Indices = a.columns[start:end] yRaw.Data[i*yRaw.Inc] += alpha * Dot(&row, x) } } }
// mulVecUnitary multiplies the receiver by the src vector, storing // the result in dst. It assumes src and dst are the same length as m // and that both have unitary vector increments. func (m rowCompressedMatrix) mulVecUnitary(dst, src *mat64.Vector) { dMat := dst.RawVector().Data for i, r := range m { dMat[i] = r.dotUnitary(src) } }
func VectorToMatrix(vector *mat64.Vector) *mat64.Dense { vec := vector.RawVector() return mat64.NewDense(1, len(vec.Data), vec.Data) }