private void Reduce(int x, int lim) { IList <PathEdge> es = pathGraph[x]; int deg = es.Count; for (int i = 0; i < deg; i++) { PathEdge e1 = es[i]; for (int j = i + 1; j < deg; j++) { PathEdge e2 = es[j]; if (!e1.Intersects(e2)) { PathEdge reduced = Reduce(e1, e2, x); if (BitArrays.Cardinality(reduced.xs) >= lim) { continue; } if (reduced.Loop()) { if (reduced.CheckPiElectrons(ps)) { reduced.Flag(aromatic); } } else { Add(reduced); } } } } pathGraph[x].Clear(); }
public void Benzylbenzene() { Graph g = Graph.FromSmiles("c1ccccc1Cc1ccccc1"); BiconnectedComponents bc = new BiconnectedComponents(g, false); Assert.AreEqual(12, BitArrays.Cardinality(bc.Cyclic)); }
public override bool Matches(IAtom atom) { if (!((IQueryAtom)query.Atoms[0]).Matches(atom)) { return(false); } if (query.Atoms.Count == 1) { return(true); } IAtomContainer target = Invariants(atom).Target; if (!cache.TryGetValue(target, out BitArray v)) { BitArray hits = new BitArray(0); foreach (var mapping in Pattern.CreateSubstructureFinder(query).MatchAll(target)) { BitArrays.SetValue(hits, mapping[0], true); } v = hits; cache[target] = v; } return(BitArrays.GetValue(v, target.Atoms.IndexOf(atom))); }
/// <summary> /// The cycle path is accepted if it does not have chord. /// </summary> /// <param name="path">a path</param> /// <param name="graph">the adjacency of atoms</param> /// <returns>accept the path as unchorded</returns> private static bool Accept(int[] path, int[][] graph) { BitArray vertices = new BitArray(0); foreach (var v in path) { BitArrays.SetValue(vertices, v, true); } for (int j = 1; j < path.Length; j++) { int v = path[j]; int prev = path[j - 1]; int next = path[(j + 1) % (path.Length - 1)]; foreach (var w in graph[v]) { // chord found if (w != prev && w != next && BitArrays.GetValue(vertices, w)) { return(false); } } } return(true); }
/// <summary> /// Create an arbitrary matching on the subset of vertices ('s') of provided /// graph. The provided matching should be empty. /// /// <param name="g">graph to match</param> /// <param name="m">empty matching (presumed)</param> /// <param name="s">subset of vertices</param> /// <returns>number of vertices matched</returns> /// </summary> public static int Initial(Graph g, Matching m, BitArray s) { int nMatched = 0; for (int v = BitArrays.NextSetBit(s, 0); v >= 0; v = BitArrays.NextSetBit(s, v + 1)) { // skip if already matched if (m.Matched(v)) { continue; } // find a single edge which is not matched and match it int d = g.Degree(v); for (int j = 0; j < d; ++j) { Edge e = g.EdgeAt(v, j); int w = e.Other(v); if ((e.Bond != Bond.Single) && m.Unmatched(w) && s[w]) { m.Match(v, w); nMatched += 2; break; } } } return(nMatched); }
public override void TestBug934819() { IAtomContainer subStructure = Bug934819_1(); IAtomContainer superStructure = Bug934819_2(); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(superStructure); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(subStructure); AddImplicitHydrogens(superStructure); AddImplicitHydrogens(subStructure); IFingerprinter fpr = new PubchemFingerprinter(); IBitFingerprint superBits = fpr.GetBitFingerprint(superStructure); IBitFingerprint subBits = fpr.GetBitFingerprint(subStructure); Assert.IsTrue(BitArrays.Equals( AsBitSet(9, 10, 14, 18, 19, 33, 143, 146, 255, 256, 283, 284, 285, 293, 301, 332, 344, 349, 351, 353, 355, 368, 370, 371, 376, 383, 384, 395, 401, 412, 416, 421, 423, 434, 441, 446, 449, 454, 455, 464, 470, 471, 480, 489, 490, 500, 502, 507, 513, 514, 516, 520, 524, 531, 532, 545, 546, 549, 552, 556, 558, 564, 570, 586, 592, 599, 600, 607, 633, 658, 665), subBits.AsBitSet())); Assert.IsTrue(BitArrays.Equals( AsBitSet(9, 10, 11, 14, 18, 19, 33, 34, 143, 146, 150, 153, 255, 256, 257, 258, 283, 284, 285, 293, 301, 332, 344, 349, 351, 353, 355, 368, 370, 371, 374, 376, 383, 384, 395, 401, 412, 416, 417, 421, 423, 427, 434, 441, 446, 449, 454, 455, 460, 464, 470, 471, 479, 480, 489, 490, 500, 502, 507, 513, 514, 516, 520, 524, 531, 532, 545, 546, 549, 552, 556, 558, 564, 570, 578, 582, 584, 586, 592, 595, 600, 603, 607, 608, 633, 634, 640, 658, 660, 664, 665, 668, 677, 678, 683), superBits.AsBitSet())); }
/// <summary> /// List all differences between the two bit vectors. Unlike /// <see cref="ListDifferences(BitArray, BitArray)"/> which only list /// those which are set in <paramref name="s"/> but not in <paramref name="t"/>. /// </summary> /// <param name="s">a bit vector</param> /// <param name="t">another bit vector</param> /// <returns>all differences between <paramref name="s"/> and <paramref name="t"/></returns> public static IReadOnlyCollection <int> Differences(BitArray s, BitArray t) { var u = (BitArray)s.Clone(); var v = (BitArray)t.Clone(); var len = Math.Max(u.Length, v.Length); if (u.Length < len) { u.Length = len; } if (v.Length < len) { v.Length = len; } u.Xor(v); var differences = new SortedSet <int>(); for (int i = BitArrays.NextSetBit(u, 0); i >= 0; i = BitArrays.NextSetBit(u, i + 1)) { differences.Add(i); } return(differences); }
/// <summary> /// Check if all the edges of the <paramref name="cycle"/> are present in the current /// <see cref="basis"/>. /// </summary> /// <param name="cycle">an initial cycle</param> /// <returns>any edges of the basis are present</returns> public bool IsSubsetOfBasis(Cycle cycle) { BitArray edgeVector = cycle.EdgeVector; int intersect = BitArrays.Cardinality(And(edgesOfBasis, edgeVector)); return(intersect == cycle.Length); }
// invariant, m is a perfect matching private static Graph Assign(Graph g, BitArray subset, BitArray aromatic, Matching m) { g.SetFlags(g.GetFlags() & ~Graph.HAS_AROM); for (int u = BitArrays.NextSetBit(aromatic, 0); u >= 0; u = BitArrays.NextSetBit(aromatic, u + 1)) { g.SetAtom(u, g.GetAtom(u).AsAliphaticForm()); int deg = g.Degree(u); for (int j = 0; j < deg; ++j) { Edge e = g.EdgeAt(u, j); int v = e.Other(u); if (v < u) { var aa = e.Bond; if (aa == Bond.Single) { if (aromatic[u] && aromatic[v]) { e.SetBond(Bond.Single); } else { e.SetBond(Bond.Implicit); } } else if (aa == Bond.Aromatic) { if (subset[u] && m.Other(u) == v) { e.SetBond(Bond.DoubleAromatic); g.UpdateBondedValence(u, +1); g.UpdateBondedValence(v, +1); } else if (aromatic[v]) { e.SetBond(Bond.ImplicitAromatic); } else { e.SetBond(Bond.Implicit); } } else if (aa == Bond.Implicit) { if (subset[u] && m.Other(u) == v) { e.SetBond(Bond.DoubleAromatic); g.UpdateBondedValence(u, +1); g.UpdateBondedValence(v, +1); } else if (aromatic[u] && aromatic[v]) { e.SetBond(Bond.ImplicitAromatic); } } } } } return(g); }
public void TestBug931608() { var builder = CDK.Builder; var filename = "NCDK.Data.MDL.bug931608-1.mol"; var ins = ResourceLoader.GetAsStream(filename); var reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict); IAtomContainer structure1 = (IAtomContainer)reader.Read(builder.NewAtomContainer()); filename = "NCDK.Data.MDL.bug931608-2.mol"; ins = ResourceLoader.GetAsStream(filename); reader = new MDLV2000Reader(ins, ChemObjectReaderMode.Strict); IAtomContainer structure2 = (IAtomContainer)reader.Read(builder.NewAtomContainer()); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(structure1); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(structure2); IFingerprinter fingerprinter = GetBitFingerprinter(); BitArray bs1 = fingerprinter.GetBitFingerprint(structure1).AsBitSet(); BitArray bs2 = fingerprinter.GetBitFingerprint(structure2).AsBitSet(); // now we do the bool XOR on the two bitsets, leading // to a bitset that has all the bits set to "true" which differ // between the two original bitsets bs1.Xor(bs2); // cardinality gives us the number of "true" bits in the // result of the XOR operation. int cardinality = BitArrays.Cardinality(bs1); Assert.AreEqual(0, cardinality); }
/// <summary> /// Attempt to augment the matching such that it is perfect over the subset /// of vertices in the provided graph. /// </summary> /// <param name="graph">adjacency list representation of graph</param> /// <param name="subset">subset of vertices</param> /// <returns>the matching was perfect</returns> /// <exception cref="ArgumentException">the graph was a different size to the matching capacity</exception> public bool Perfect(int[][] graph, BitArray subset) { if (graph.Length != match.Length || BitArrays.Cardinality(subset) > graph.Length) { throw new ArgumentException("graph and matching had different capacity"); } // and odd set can never provide a perfect matching if ((BitArrays.Cardinality(subset) & 0x1) == 0x1) { return(false); } // arbitrary matching was perfect if (ArbitaryMatching(graph, subset)) { return(true); } EdmondsMaximumMatching.Maxamise(this, graph, subset); // the matching is imperfect if any vertex was for (int v = BitArrays.NextSetBit(subset, 0); v >= 0; v = BitArrays.NextSetBit(subset, v + 1)) { if (Unmatched(v)) { return(false); } } return(true); }
public override bool Equals(object obj) { if (this == obj) { return(true); } if (obj == null) { return(false); } if (GetType() != obj.GetType()) { return(false); } var other = (BitSetFingerprint)obj; if (bitset == null) { if (other.bitset != null) { return(false); } } else if (!BitArrays.Equals(bitset, other.bitset)) { return(false); } return(true); }
public static Graph GenerateKekuleForm(Graph g, BitArray subset, BitArray aromatic, bool inplace) { // make initial (empty) matching - then improve it, first // by matching the first edges we find, most of time this // gives us a perfect matching if not we maximise it // with Edmonds' algorithm Matching m = Matching.CreateEmpty(g); int n = BitArrays.Cardinality(subset); int nMatched = ArbitraryMatching.Initial(g, m, subset); if (nMatched < n) { if (n - nMatched == 2) { nMatched = ArbitraryMatching.AugmentOnce(g, m, nMatched, subset); } if (nMatched < n) { nMatched = MaximumMatching.Maximise(g, m, nMatched, IntSet.FromBitArray(subset)); } if (nMatched < n) { throw new InvalidSmilesException("Could not Kekulise"); } } return(inplace ? Assign(g, subset, aromatic, m) : CopyAndAssign(g, subset, aromatic, m)); }
public override void TestBug706786() { IAtomContainer superStructure = Bug706786_1(); IAtomContainer subStructure = Bug706786_2(); AddImplicitHydrogens(superStructure); AddImplicitHydrogens(subStructure); // SMARTS is now correct and D will include H atoms, CDK had this wrong // for years (had it has non-H count). Whilst you can set the optional // SMARTS flavor CDK_LEGACY this is not correct AtomContainerManipulator.SuppressHydrogens(superStructure); AtomContainerManipulator.SuppressHydrogens(subStructure); IFingerprinter fpr = GetBitFingerprinter(); IBitFingerprint superBits = fpr.GetBitFingerprint(superStructure); IBitFingerprint subBits = fpr.GetBitFingerprint(subStructure); Assert.IsTrue(BitArrays.Equals( AsBitSet(0, 11, 13, 17, 40, 48, 136, 273, 274, 278, 286, 294, 299, 301, 304, 306), superBits.AsBitSet())); Assert.IsTrue(BitArrays.Equals( AsBitSet(1, 17, 273, 274, 278, 294, 306), subBits.AsBitSet())); }
public void ImperfectArbitaryMatching() { Matching matching = Matching.WithCapacity(5); BitArray subset = new BitArray(5); BitArrays.Flip(subset, 0, 5); Assert.IsFalse(matching.ArbitaryMatching(new int[][] { new[] { 1 }, new[] { 0, 2 }, new[] { 1, 3 }, new[] { 2, 4 }, new[] { 3 } }, subset)); }
public void PerfectArbitaryMatching() { Matching matching = Matching.WithCapacity(4); BitArray subset = new BitArray(4); BitArrays.Flip(subset, 0, 4); Assert.IsTrue(matching.ArbitaryMatching(new int[][] { new[] { 1 }, new[] { 0, 2 }, new[] { 1, 3 }, new[] { 2 } }, subset)); }
public void Flag(bool[] mark) { mark[u] = true; for (int i = BitArrays.NextSetBit(xs, 0); i >= 0; i = BitArrays.NextSetBit(xs, i + 1)) { mark[i] = true; } }
public void Fulvelene1() { int[][] graph = GraphUtil.ToAdjList(smipar.ParseSmiles("c1cccc1c1cccc1")); Matching m = Matching.WithCapacity(graph.Length); BitArray subset = new BitArray(graph.Length); BitArrays.Flip(subset, 0, graph.Length); // arbitary matching will assign a perfect matching here Assert.IsTrue(m.ArbitaryMatching(graph, subset)); }
public virtual void Duplicates() { // ensure duplicates are handled BitMatrix m = new BitMatrix(9, 3); m.Add(BitArrays.FromString("110000000")); m.Add(BitArrays.FromString("110000000")); m.Add(BitArrays.FromString("001100000")); Assert.AreEqual(2, m.Eliminate()); }
public static BitArray AsBitSet(params int[] xs) { BitArray bs = new BitArray(0); foreach (var x in xs) { BitArrays.SetValue(bs, x, true); } return(bs); }
public virtual void Xor() { BitArray s = BitArrays.FromString("00011"); BitArray t = BitArrays.FromString("10010"); BitArray u = BitMatrix.Xor(s, t); Assert.AreNotSame(u, s); Assert.AreNotSame(u, t); Assert.IsTrue(Compares.AreDeepEqual(BitArrays.FromString("10001"), u)); }
/// <summary> /// Convert a mapping to a bitset. /// </summary> /// <param name="mapping">an atom mapping</param> /// <returns>a bit set of the mapped vertices (values in array)</returns> private static BitArray ToBitArray(int[] mapping) { BitArray hits = new BitArray(0); foreach (var v in mapping) { BitArrays.SetValue(hits, v, true); } return(hits); }
/// <summary> /// Create a new multiple stereo encoder from a single list of encoders /// </summary> public MultiStereoEncoder(IList <IStereoEncoder> encoders) { if (encoders.Count == 0) { throw new ArgumentException("no stereo encoders provided"); } this.encoders = new List <IStereoEncoder>(encoders); this.unconfigured = new BitArray(encoders.Count); BitArrays.Flip(unconfigured, encoders.Count); }
/// <summary> /// Find the next index that the <i>cycle</i> intersects with by at least two /// vertices. If the intersect of a vertex set with another contains more /// then two vertices it cannot be edge disjoint. /// </summary> /// <param name="start">start searching from here</param> /// <param name="cycle">test whether any current cycles are fused with this one</param> /// <returns>the index of the first fused after 'start', -1 if none</returns> private int IndexOfFused(int start, BitArray cycle) { for (int i = start; i < cycles.Count(); i++) { if (BitArrays.Cardinality(And(cycles[i], cycle)) > 1) { return(i); } } return(-1); }
/// <summary> /// Converts a CDKRGraph bitset (set of CDKRNode) /// to a list of CDKRMap that represents the /// mapping between to substructures in G1 and G2 /// (the projection of the CDKRGraph bitset on G1 /// and G2). /// /// <param name="set">the BitArray</param> /// <returns>the CDKRMap list</returns> /// </summary> public IReadOnlyList <CDKRMap> BitSetToRMap(BitArray set) { List <CDKRMap> rMapList = new List <CDKRMap>(); for (int x = BitArrays.NextSetBit(set, 0); x >= 0; x = BitArrays.NextSetBit(set, x + 1)) { CDKRNode xNode = Graph[x]; rMapList.Add(xNode.RMap); } return(rMapList); }
public void TestFingerprinterBitSetSize() { Fingerprinter fingerprinter = new Fingerprinter(1024, 7); Assert.IsNotNull(fingerprinter); var mol = TestMoleculeFactory.MakeIndole(); BitArray bs = fingerprinter.GetBitFingerprint(mol).AsBitSet(); Assert.AreEqual(994, BitArrays.GetLength(bs)); // highest set bit Assert.AreEqual(1024, bs.Count); // actual bit set size }
public virtual void StRingTest() { BitMatrix m = new BitMatrix(9, 3); m.Add(BitArrays.FromString("110000000")); m.Add(BitArrays.FromString("110011000")); m.Add(BitArrays.FromString("000011000")); string str = m.ToString(); Assert.AreEqual("0: 11-------\n" + "1: 11--11---\n" + "2: ----11---\n", str); }
public object Visit(ASTChirality node, object data) { var atom = new ChiralityAtom(builder) { IsClockwise = node.IsClockwise, IsUnspecified = node.IsUnspecified }; BitArrays.SetValue(tetrahedral, query.Atoms.Count, true); return(atom); }
public override int[] ToArray() { int[] xs = new int[Count]; int n = 0; for (int i = BitArrays.NextSetBit(set, 0); i >= 0; i = BitArrays.NextSetBit(set, i + 1)) { xs[n++] = i; } return(xs); }
public bool this[int index] { get { return(BitArrays.GetValue(bitset, index)); } set { BitArrays.SetValue(bitset, index, value); } }