// Mul computes the product of two matrices a,b and puts // it in receiver. // a = mxk, b = kxn, c = mxn func (c *mesh) Mul(s float64, a, b Mesher) { m, k := a.Size() br, n := b.Size() var ( icoff, iaoff, lboff int ctmp []float64 tmp float64 ) if k != br { panic("mesh: Mul: Columns of 'a' != Rows of 'b'") } aoff, boff, coff := k, n, n for i := 0; i < m; i++ { icoff = i * coff iaoff = i * aoff ctmp = c.elems[icoff : icoff+n] for l, v := range a.(*mesh).elems[iaoff : iaoff+k] { lboff = l * boff tmp = s * v if tmp != 0 { amd.DaxpyUnitary(tmp, b.(*mesh).elems[lboff:lboff+n], ctmp, ctmp) } } } }
// Sum computes the sum of meshes, m & n and puts // result in receiver. // m, n and o should have same dimensions. // a*m + n = o // we will calculate the sum of meshes using // a slight variation of saxpy // ie ax+by, x and y are vectors and // a, b are scalars. func (o *mesh) Sum(a, b float64, m, n Mesher) { // the size of all the meshes are assumed to be // equal and no check is performed, we want this // to be as fast an operation as possible _, mc := m.Size() // no. of cols of the meshes mv := make([]float64, mc) // col vector of m nv := make([]float64, mc) // col vector of n ov := make([]float64, mc) // col vector of o // we will scale the meshes if a == 0 && b == 1 { // z = 0*x + y // we just copy n into o o.Clone(n) return } if b == 0 && a == 1 { // z = x + 0*y // we just copy m into o o.Clone(m) return } if a == 1 && b != 1 { // z = x + by // we scale n ns := n.Slice() for j := range ns { ns[j] *= b } } else if a != 1 && b == 1 { // z = ax + y // we scale m ms := m.Slice() for j := range ms { ms[j] *= a } } else if a == 0 && b == 0 { o.Zero() return } // we add the meshes by cols for j := 0; j < mc; j++ { m.GetCol(mv, j) n.GetCol(nv, j) amd.DaxpyUnitary(a, mv, nv, ov) o.SetCol(ov, j) } }
// Sum computes the sum of two vectors func Sum(s float64, a, b, c []float64) { amd.DaxpyUnitary(s, a, b, c) }