/* 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 }
/* 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 }
/* The vector x is an element of S, with the 's' components stored in unpacked storage and off-diagonal entries scaled by sqrt(2). On return, x is copied to y with the 's' components stored in unpacked storage. */ func unpack(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") err = blas.Copy(x, y, &la_.IOpt{"n", nlq}, &la_.IOpt{"offsetx", offsetx}, &la_.IOpt{"offsety", offsety}) if err != nil { return } ip, iu := offsetx+nlq, offsety+nlq for _, n := range dims.At("s") { for k := 0; k < n; k++ { err = blas.Copy(x, y, &la_.IOpt{"n", n - k}, &la_.IOpt{"offsetx", ip}, &la_.IOpt{"offsety", iu + k*(n+1)}) if err != nil { return } ip += n - k blas.ScalFloat(y, 1.0/math.Sqrt(2.0), &la_.IOpt{"n", n - k - 1}, &la_.IOpt{"offset", iu + k*(n+1) + 1}) } iu += n * n } /* nu := dims.SumSquared("s") fmt.Printf("-- UnPack: nu=%d, offset=%d\n", nu, offsety+nlq) err = blas.ScalFloat(y, &la_.IOpt{"n", nu}, &la_.IOpt{"offset", offsety+nlq}) */ return }