func (w *Walker) SelectionProbability(Q_, R_, u_ *Sparse) (float64, error) { Q := Q_.Dense() R := R_.Dense() u := u_.Dense() I := matrix.Eye(Q.Rows()) IQ, err := I.Minus(Q) if err != nil { return 0, err } N := matrix.Inverse(IQ) B, err := N.Times(R) if err != nil { return 0, err } P, err := u.Times(B) if err != nil { return 0, err } if P.Rows() != P.Cols() && P.Rows() != 1 { return 0, errors.Errorf("Unexpected P shape %v %v", P.Rows(), P.Cols()) } x := P.Get(0, 0) if x > 1.0 || x != x { return 0, errors.Errorf("could not accurately compute p") } return x, nil }
func (emb *Embedding) UnmarshalBinary(bytes []byte) error { if emb.SG != nil || emb.Ids != nil { return errors.Errorf("Embedding is already loaded! will not load serialized data") } if len(bytes) < 8 { return errors.Errorf("bytes was too small %v < 8", len(bytes)) } lenE := int(binary.BigEndian.Uint32(bytes[0:4])) lenV := int(binary.BigEndian.Uint32(bytes[4:8])) off := 8 expected := 8 + lenV*8 + lenE*12 if len(bytes) < expected { return errors.Errorf("bytes was too small %v < %v", len(bytes), expected) } ids := make([]int, lenV) sg := &SubGraph{ V: make([]Vertex, lenV), E: make([]Edge, lenE), Adj: make([][]int, lenV), } for i := 0; i < lenV; i++ { s := off + i*8 e := s + 4 id := int(binary.BigEndian.Uint32(bytes[s:e])) s += 4 e += 4 color := int(binary.BigEndian.Uint32(bytes[s:e])) ids[i] = id sg.V[i].Idx = i sg.V[i].Color = color sg.Adj[i] = make([]int, 0, 5) } off += lenV * 8 for i := 0; i < lenE; i++ { s := off + i*12 e := s + 4 src := int(binary.BigEndian.Uint32(bytes[s:e])) s += 4 e += 4 targ := int(binary.BigEndian.Uint32(bytes[s:e])) s += 4 e += 4 color := int(binary.BigEndian.Uint32(bytes[s:e])) sg.E[i].Src = src sg.E[i].Targ = targ sg.E[i].Color = color sg.Adj[src] = append(sg.Adj[src], i) sg.Adj[targ] = append(sg.Adj[targ], i) } emb.SG = sg emb.Ids = ids return nil }
func CommonAncestor(patterns []lattice.Pattern) (_ lattice.Pattern, err error) { if len(patterns) == 0 { return nil, errors.Errorf("no patterns given") } else if len(patterns) == 1 { return patterns[0], nil } switch patterns[0].(type) { case *digraph.SubgraphPattern: return digraphCommonAncestor(patterns) case *itemset.Pattern: return itemsetCommonAncestor(patterns) default: return nil, errors.Errorf("unknown pattern type %v", patterns[0]) } }
func digraphItemset(n *digraph.EmbListNode, attr string) (types.Set, error) { dt := n.Dt embs, err := n.Embeddings() if err != nil { return nil, err } s := set.NewSortedSet(len(embs)) for _, emb := range embs { for _, vid := range emb.Ids { err := dt.NodeAttrs.DoFind( int32(vid), func(_ int32, attrs map[string]interface{}) error { if val, has := attrs[attr]; has { switch v := val.(type) { case string: s.Add(types.String(v)) case int: s.Add(types.Int(v)) default: return errors.Errorf("DBSCAN does not yet support attr type %T", val) } } return nil }) if err != nil { return nil, err } } } return s, nil }
func (f *Formatter) Pattern(node lattice.Node) (string, error) { switch n := node.(type) { case *EmbListNode: if len(n.embeddings) > 0 { Pat := n.Pat.Pretty(n.Dt.Labels) allAttrs, err := f.loadAttrs(n.embeddings[0]) if err != nil { return "", err } attrs := make(map[int]map[string]interface{}) for id, _ := range allAttrs { attrs[id] = make(map[string]interface{}) if size, has := allAttrs[id]["fontsize"]; has { attrs[id]["fontsize"] = size } } dot := n.embeddings[0].Dotty(n.Dt.Labels, attrs) return fmt.Sprintf("// %s\n\n%s\n", Pat, dot), nil } else { return fmt.Sprintf("// {0:0}\n\ndigraph{}\n"), nil } default: return "", errors.Errorf("unknown node type %v", node) } }
func mapEntry(item types.Hashable) (*types.MapEntry, error) { if me, ok := item.(*types.MapEntry); ok { return me, nil } else { return nil, errors.Errorf("Must pass a *types.MapEntry, got %T", item) } }
func CPUProfile(cpuProfile string) func() { errors.Logf("DEBUG", "starting cpu profile: %v", cpuProfile) f, err := os.Create(cpuProfile) if err != nil { log.Fatal(err) } err = pprof.StartCPUProfile(f) if err != nil { log.Fatal(err) } sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { sig := <-sigs errors.Logf("DEBUG", "closing cpu profile") pprof.StopCPUProfile() err := f.Close() errors.Logf("DEBUG", "closed cpu profile, err: %v", err) panic(errors.Errorf("caught signal: %v", sig)) }() return func() { errors.Logf("DEBUG", "closing cpu profile") pprof.StopCPUProfile() err := f.Close() errors.Logf("DEBUG", "closed cpu profile, err: %v", err) } }
func (l *List) Set(i int, item types.Hashable) (err error) { if i < 0 || i >= len(l.list) { return errors.Errorf("Access out of bounds. len(*List) = %v, idx = %v", len(l.list), i) } l.list[i] = item return nil }
func (self *Int16) UnmarshalBinary(data []byte) error { if len(data) != 2 { return errors.Errorf("data wrong size") } *self = Int16(binary.LittleEndian.Uint16(data)) return nil }
func (self *UInt8) UnmarshalBinary(data []byte) error { if len(data) != 1 { return errors.Errorf("data wrong size") } *self = UInt8(data[0]) return nil }
func (self *UInt) UnmarshalBinary(data []byte) error { if len(data) != 4 { return errors.Errorf("data wrong size") } *self = UInt(binary.LittleEndian.Uint32(data)) return nil }
func (b *Builder) droppedVertexOnEdgeRm(edgeIdx int) (drop bool, idx int, err error) { edge := &b.E[edgeIdx] rmSrc := true rmTarg := true for i := range b.E { e := &b.E[i] if e == edge { continue } if edge.Src == e.Src || edge.Src == e.Targ { // a kid edge rmSrc = false } if edge.Targ == e.Src || edge.Targ == e.Targ { // a parent edge rmTarg = false } } if rmSrc && rmTarg { return false, 0, errors.Errorf("would have removed both source and target %v %v", rmSrc, rmTarg) } rmV := rmSrc || rmTarg var rmVidx int if rmSrc { rmVidx = edge.Src } if rmTarg { rmVidx = edge.Targ } return rmV, rmVidx, nil }
func Transition(cur lattice.Node, adjs []lattice.Node, weight Weight, debug bool) (float64, lattice.Node, error) { if len(adjs) <= 0 { return 1, nil, nil } if len(adjs) == 1 { return 1, adjs[0], nil } prs, err := TransitionPrs(cur, adjs, weight, debug) if err != nil { return 0, nil, err } else if prs == nil { return 1, nil, nil } s := stats.Round(stats.Sum(prs), 3) if s != 1.0 { weights := make([]float64, 0, len(adjs)) for _, v := range adjs { wght, _ := weight(cur, v) weights = append(weights, wght) } return 0, nil, errors.Errorf("sum(%v) (%v) != 1.0 from %v", prs, s, weights) } i := stats.WeightedSample(prs) return prs[i], adjs[i], nil }
func labelset(node lattice.Node) (types.Set, error) { switch n := node.(type) { case *digraph.EmbListNode: return digraphLabelset(n) default: return nil, errors.Errorf("DBSCAN does not yet support %T", n) } }
func itemset(node lattice.Node, attr string) (types.Set, error) { switch n := node.(type) { case *digraph.EmbListNode: return digraphItemset(n, attr) default: return nil, errors.Errorf("DBSCAN does not yet support %T", n) } }
func (sg *SubGraph) UnmarshalBinary(bytes []byte) error { if sg.V != nil || sg.E != nil || sg.Adj != nil { return errors.Errorf("sg is already loaded! will not load serialized data") } if len(bytes) < 8 { return errors.Errorf("bytes was too small %v < 8", len(bytes)) } lenE := int(binary.BigEndian.Uint32(bytes[0:4])) lenV := int(binary.BigEndian.Uint32(bytes[4:8])) off := 8 expected := 8 + lenV*4 + lenE*12 if len(bytes) < expected { return errors.Errorf("bytes was too small %v < %v", len(bytes), expected) } sg.V = make([]Vertex, lenV) sg.E = make([]Edge, lenE) sg.Adj = make([][]int, lenV) for i := 0; i < lenV; i++ { s := off + i*4 e := s + 4 color := int(binary.BigEndian.Uint32(bytes[s:e])) sg.V[i].Idx = i sg.V[i].Color = color sg.Adj[i] = make([]int, 0, 5) } off += lenV * 4 for i := 0; i < lenE; i++ { s := off + i*12 e := s + 4 src := int(binary.BigEndian.Uint32(bytes[s:e])) s += 4 e += 4 targ := int(binary.BigEndian.Uint32(bytes[s:e])) s += 4 e += 4 color := int(binary.BigEndian.Uint32(bytes[s:e])) sg.E[i].Src = src sg.E[i].Targ = targ sg.E[i].Color = color sg.Adj[src] = append(sg.Adj[src], i) sg.Adj[targ] = append(sg.Adj[targ], i) } sg.labelCache = bytes return nil }
func (s *SortedSet) Random() (item types.Hashable, err error) { if s.Size() <= 0 { return nil, errors.Errorf("Set is empty") } else if s.Size() <= 1 { return s.Get(0) } i := rand.Intn(s.Size()) return s.Get(i) }
func (s *Sorted) Item(item types.Hashable) (types.Hashable, error) { i, has, err := s.Find(item) if err != nil { return nil, err } else if !has { return nil, errors.Errorf("Item not found %v", item) } return s.Get(i) }
func LoadNode(items []int32, dt *ItemSets) (n *Node, err error) { n, err = TryLoadNode(items, dt) if err != nil { return nil, err } else if n == nil { return nil, errors.Errorf("Expected node %v to be in embeddings store but it wasn't", items) } return n, nil }
func (l *baseLoader) addEdge(sid, tid int32, color int, label string) (err error) { if l.excluded[sid] || l.excluded[tid] { return nil } if l.dt.Include != nil && !l.dt.Include.MatchString(label) { return nil } if l.dt.Exclude != nil && l.dt.Exclude.MatchString(label) { return nil } if sidx, has := l.vidxs[sid]; !has { return errors.Errorf("unknown src id %v", tid) } else if tidx, has := l.vidxs[tid]; !has { return errors.Errorf("unknown targ id %v", tid) } else { l.b.AddEdge(&l.b.V[sidx], &l.b.V[tidx], color) } return nil }
func (s *Sorted) Delete(item types.Hashable) (err error) { i, has, err := s.Find(item) if err != nil { return err } else if !has { return errors.Errorf("item %v not in the table", item) } return s.list.Remove(i) return nil }
func VE(node lattice.Node) (V, E int) { E = 0 V = 0 switch n := node.(type) { case *EmbListNode: return len(n.Pat.V), len(n.Pat.E) default: panic(errors.Errorf("unknown node type %T %v", node, node)) } return V, E }
func (b *Builder) Extend(e *Extension) (newe *Edge, newv *Vertex, err error) { if e.Source.Idx > len(b.V) { return nil, nil, errors.Errorf("Source.Idx %v outside of |V| %v", e.Source.Idx, len(b.V)) } else if e.Target.Idx > len(b.V) { return nil, nil, errors.Errorf("Target.Idx %v outside of |V| %v", e.Target.Idx, len(b.V)) } else if e.Source.Idx == len(b.V) && e.Target.Idx == len(b.V) { return nil, nil, errors.Errorf("Only one new vertice allowed (Extension would create a disconnnected graph)") } var src *Vertex = &e.Source var targ *Vertex = &e.Target if e.Source.Idx == len(b.V) { src = b.AddVertex(e.Source.Color) newv = src } else if e.Target.Idx == len(b.V) { targ = b.AddVertex(e.Target.Color) newv = targ } newe = b.AddEdge(src, targ, e.Color) return newe, newv, nil }
func (l *List) Remove(i int) error { if i < 0 || i >= len(l.list) { return errors.Errorf("Access out of bounds. len(*List) = %v, idx = %v", len(l.list), i) } dst := l.list[i : len(l.list)-1] src := l.list[i+1 : len(l.list)] copy(dst, src) l.list = l.list[:len(l.list)-1] l.shrink() return nil }
func (f *Formatter) PatternName(node lattice.Node) string { switch n := node.(type) { case *EmbListNode: if len(n.embeddings) > 0 { return n.Pat.Pretty(n.Dt.Labels) } else { return "0:0" } default: panic(errors.Errorf("unknown node type %v", node)) } }
func (l *List) expand() error { if l.fixed { return errors.Errorf("Fixed size list is full!") } list := l.list if cap(list) < 100 { l.list = make([]types.Hashable, len(list), cap(list)*2) } else { l.list = make([]types.Hashable, len(list), cap(list)+100) } copy(l.list, list) return nil }
func isCanonicalExtension(cur *subgraph.SubGraph, ext *subgraph.SubGraph) (bool, error) { // errors.Logf("DEBUG", "is %v a canonical ext of %v", ext.Label(), n) parent, err := firstParent(subgraph.Build(len(ext.V), len(ext.E)).From(ext)) if err != nil { return false, err } else if parent == nil { return false, errors.Errorf("ext %v of node %v has no parents", ext, cur) } if bytes.Equal(parent.Build().Label(), cur.Label()) { return true, nil } return false, nil }
func firstParent(b *subgraph.Builder) (_ *subgraph.Builder, err error) { if len(b.E) <= 0 { return nil, nil } parents := make([]*subgraph.Builder, 0, 10) for i := len(b.E) - 1; i >= 0; i-- { parents, err = computeParent(b, i, parents) if err != nil { return nil, err } if len(parents) > 0 { return parents[0], nil } } return nil, errors.Errorf("no parents for %v", b) }
func parents(n Node, parents bytes_bytes.MultiMap, parentCount bytes_int.MultiMap) (nodes []lattice.Node, err error) { // errors.Logf("DEBUG", "compute Parents\n of %v", n) if n.isRoot() { return []lattice.Node{}, nil } dt := n.dt() sg := n.SubGraph() if len(sg.V) == 1 && len(sg.E) == 0 { return []lattice.Node{dt.Root()}, nil } if nodes, has, err := cachedAdj(n, dt, dt.ParentCount, dt.Parents); err != nil { return nil, err } else if has { return nodes, nil } parentBuilders, err := AllParents(n.SubGraph().Builder()) if err != nil { return nil, err } seen := set.NewSortedSet(10) nodes = make([]lattice.Node, 0, 10) for _, pBuilder := range parentBuilders { parent := pBuilder.Build() if seen.Has(parent) { continue } seen.Add(parent) support, pexts, pembs, poverlap, punsupEmbs, err := ExtsAndEmbs(dt, parent, nil, set.NewSortedSet(0), nil, dt.Mode, false) if err != nil { return nil, err } if support < dt.Support() { // this means this parent support comes from automorphism // it isn't truly supported, and its children may be spurious as well // log and skip? ExtsAndEmbs(dt, parent, nil, set.NewSortedSet(0), nil, dt.Mode, true) errors.Logf("WARN", "for node %v parent %v had support %v less than required %v due to automorphism", n, parent.Pretty(dt.Labels), support, dt.Support()) } else { nodes = append(nodes, n.New(parent, pexts, pembs, poverlap, punsupEmbs)) } } if len(nodes) == 0 { return nil, errors.Errorf("Found no parents!!\n node %v", n) } return nodes, cacheAdj(dt, dt.ParentCount, dt.Parents, n.Label(), nodes) }
func MakeUniformWalk(restartPr float64, selfTransition bool) walker.Walk { return func(w *walker.Walker) (chan lattice.Node, chan bool, chan error) { samples := make(chan lattice.Node) terminate := make(chan bool) errs := make(chan error) go func() { cur := w.Dt.Root() loop: for { samples <- cur if <-terminate { break loop } if rand.Float64() < restartPr { errors.Logf("INFO", "a random restart occured with probability %v", restartPr) cur = w.Dt.Root() } else { curLabel := cur.Pattern().Label() nextLabel := curLabel var next lattice.Node = nil for bytes.Equal(curLabel, nextLabel) { var err error next, err = Next(w, cur) if err != nil { errs <- err break loop } if next == nil { errs <- errors.Errorf("next was nil!!") break loop } nextLabel = next.Pattern().Label() if selfTransition { break } } cur = next } } close(samples) close(errs) }() return samples, terminate, errs } }