func TestLeastSquares(t *testing.T) { matA := mat64.NewDense(5, 3, []float64{ 1, -2, 4, 1, -1, 1, 1, 0, 0, 1, 1, 1, 1, 2, 4, }) vecb := mat64.NewVector(5, []float64{ 0, 0, 1, 0, 0, }) x := vec3(linalg.LeastSquares(matA, vecb)) expected := Vec3{34.0 / 70.0, 0.0, -10.0 / 70.0} if x != expected { t.Errorf("expected %v, got %v", expected, x) } }
func Dual(f F, df DF, size int) (vertices []Vec3, faces [][3]int) { hdata := make([][2]Vec3, 0, 8) a := make([]float64, 0, 8*3) b := make([]float64, 0, 8) vindex := make(map[Vec3]int) it := cartesian(size, size, size) for x, y, z, next := it(); next; x, y, z, next = it() { o := Vec3{float64(x), float64(y), float64(z)} var signs [8]bool for i, v := range cube { signs[i] = f(o.Add(v)) > 0 } hdata = hdata[0:0] for _, e := range edges { if signs[e[0]] == signs[e[1]] { continue } h := hermite(f, df, o.Add(cube[e[0]]), o.Add(cube[e[1]])) hdata = append(hdata, h) } a = a[0:0] for _, h := range hdata { a = append(a, h[1][:]...) } b = b[0:0] for _, h := range hdata { b = append(b, h[0].Dot(h[1])) } mata := mat64.NewDense(len(b), 3, a) vecb := mat64.NewVector(len(b), b) v := vec3(linalg.LeastSquares(mata, vecb)) if v.Sub(o).Len() > 1.5 { continue } vindex[o] = len(vertices) vertices = append(vertices, v) } it = cartesian(size, size, size) for x, y, z, next := it(); next; x, y, z, next = it() { o := Vec3{float64(x), float64(y), float64(z)} var ok bool var o0 int if o0, ok = vindex[o]; !ok { continue } for i := 0; i < 3; i++ { for j := 0; j < i; j++ { var oi, oj, oij int if oi, ok = vindex[o.Add(base[i])]; !ok { continue } if oj, ok = vindex[o.Add(base[j])]; !ok { continue } if oij, ok = vindex[o.Add(base[i].Add(base[j]))]; !ok { continue } faces = append(faces, [3]int{o0, oi, oj}, [3]int{oij, oj, oi}) } } } return vertices, faces }