简体   繁体   中英

Gonum throws bad region panic when using an embedded struct

I am using gonum to perform a few linear algebra calculations. After extending the original mat.VecDense struct I am getting a "bad region: identical" panic when applying a method on itself. This error does not occur when I am using the original setup gonum provides.

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 :

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.

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. 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.

In Golang it is described for promoted methods as

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:

  • If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.
  • If S contains an embedded field *T, the method sets of S and *S both include promoted methods with receiver T or *T.

The problem is that you are passing pointer type arguments to AddVec function. 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

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.AddVec(x, y)

The problem is that the pointers are compared when doing shadow detection. This is a bug IMO. I just filed https://github.com/gonum/gonum/issues/945

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM