[英]Gonum throws bad region panic when using an embedded struct
I am using gonum to perform a few linear algebra calculations. 我正在使用gonum执行一些线性代数计算。 After extending the original
mat.VecDense
struct I am getting a "bad region: identical" panic when applying a method on itself. 扩展了原始的
mat.VecDense
结构后,在对其自身应用方法时,我遇到了“错误区域:相同”的恐慌。 This error does not occur when I am using the original setup gonum provides. 当我使用gonum提供的原始安装程序时,不会发生此错误。
Here is my implementation: 这是我的实现:
type Vector struct {
mat.VecDense
}
func NewVector(n int, data []float64) *Vector {
return &Vector{*mat.NewVecDense(n, data)}
}
I am testing it using the following snippet: 我正在使用以下代码段对其进行测试:
func main() {
u, v := mat.NewVecDense(3, []float64{1, 2, 3}), mat.NewVecDense(3, []float64{4, 5, 6})
fmt.Printf("[U - NewVecDense]\tADDRESS: %v, VALUE: %v\n", &u, u)
fmt.Printf("[V - NewVecDense]\tADDRESS: %v, VALUE: %v\n", &v, v)
u.AddVec(u, v)
fmt.Println("-------------------------")
x, y := NewVector(3, []float64{1, 2, 3}), NewVector(3, []float64{4, 5, 6})
fmt.Printf("[X - NewVector]\tADDRESS: %v, VALUE: %v\n", &x, x)
fmt.Printf("[Y - NewVector]\tADDRESS: %v, VALUE: %v\n", &y, y)
x.AddVec(x, y)
fmt.Println(x)
}
While the first addition executes fine, the second fails: 当第一个加法执行正常时,第二个加法失败:
[U - NewVecDense] ADDRESS: 0xc42000c028, VALUE: &{{[1 2 3] 1} 3}
[V - NewVecDense] ADDRESS: 0xc42000c030, VALUE: &{{[4 5 6] 1} 3}
-------------------------
[X - NewVector] ADDRESS: 0xc42000c040, VALUE: &{{{[1 2 3] 1} 3}}
[Y - NewVector] ADDRESS: 0xc42000c048, VALUE: &{{{[4 5 6] 1} 3}}
panic: mat: bad region: identical
AddVec
is a method implemented by gonum : AddVec
是由gonum实现的方法:
func (v *VecDense) AddVec(a, b Vector)
Why is this happening, hand what is the right way of implementing this? 为什么会发生这种情况,请问实施此方法的正确方法是什么?
Edit: 编辑:
Thanks to @Himanshu I managed to solve the problem. 感谢@Himanshu,我设法解决了这个问题。
I created pass-through methods for each method I am using, passing the right level of the struct through: 我为正在使用的每个方法创建了传递方法,将结构的正确级别传递给了:
type Vector struct {
*mat.VecDense
}
func NewVector(n int, data []float64) Vector {
return Vector{mat.NewVecDense(n, data)}
}
func (v *Vector) AddVec(a, b Vector) {
v.VecDense.AddVec(a.VecDense, b.VecDense)
}
func (v *Vector) SubVec(a, b Vector) {
v.VecDense.SubVec(a.VecDense, b.VecDense)
}
func (v *Vector) ScaleVec(alpha float64, a Vector) {
v.VecDense.ScaleVec(alpha, a.VecDense)
}
func (v *Vector) AddScaledVec(a Vector, alpha float64, b Vector) {
v.VecDense.AddScaledVec(a.VecDense, alpha, b.VecDense)
}
In addition - I am not sure if this is the right approach or not - I have also changed the return type for NewVector
from pointer to value, since it holds a pointer to the mat.VecDense
anyway. 另外-我不确定这是否是正确的方法-我也将
NewVector
的返回类型从指针更改为value,因为它仍然持有指向mat.VecDense
的指针。 Note that *mat.VecDense
satisfies the Vector
interface from gonum, so passing this internal field on to the methods worked fine, as the example above shows. 请注意,
*mat.VecDense
满足*mat.VecDense
的Vector
接口,因此将此内部字段传递给方法可以正常工作,如上面的示例所示。
In Golang it is described for promoted methods as 在Golang中,它对提升方法的描述如下:
Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.
提升的字段的行为类似于结构的普通字段,只是它们不能用作结构的复合文字中的字段名称。
Given a struct type S and a defined type T, promoted methods are included in the method set of the struct as follows: 给定一个结构类型S和一个定义的类型T,在该方法的方法集中包括了以下改进的方法:
The problem is that you are passing pointer type arguments to AddVec
function. 问题是您将指针类型参数传递给
AddVec
函数。 But you are using pointer type fields in second case. 但是在第二种情况下,您使用的是指针类型字段。
func (v *VecDense) AddVec(a, b Vector)
One more thing to notice is that AddVec
has value type arguments of Vector
struct but you are passing pointer to Vector
fields as 需要注意的另一件事是
AddVec
具有Vector
结构的值类型参数,但是您正在将指向Vector
字段的指针传递为
x, y := NewVector(3, []float64{1, 2, 3}), NewVector(3, []float64{4, 5, 6})
In above code x,y
are pointer type returned from NewVector
在上面的代码
x,y
是从NewVector
返回的指针类型
x.AddVec(x, y)
The problem is that the pointers are compared when doing shadow detection. 问题是进行阴影检测时会比较指针。 This is a bug IMO.
这是IMO的错误。 I just filed https://github.com/gonum/gonum/issues/945
我刚刚提交了https://github.com/gonum/gonum/issues/945
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.