/// <summary> /// Create a perturbed hash generator using the provided seed generator to /// initialise atom invariants and using the provided stereo factory. /// </summary> /// <param name="seeds"></param> /// <param name="simple">generator to encode the initial values of atoms</param> /// <param name="pseudorandom">pseudorandom number generator used to randomise hash distribution</param> /// <param name="factory">a stereo encoder factory</param> /// <param name="finder">equivalent set finder for driving the systematic perturbation</param> /// <param name="suppression">suppression of atoms (these atoms are 'ignored' in the hash generation)</param> /// <exception cref="ArgumentException">depth was less then 0</exception> /// <exception cref="ArgumentNullException"> seed generator or pseudo random was null</exception> /// <seealso cref="SeedGenerator"/> public PerturbedAtomHashGenerator(SeedGenerator seeds, AbstractAtomHashGenerator simple, Pseudorandom pseudorandom, IStereoEncoderFactory factory, EquivalentSetFinder finder, AtomSuppression suppression) : base(pseudorandom) { this.finder = finder; this.factory = factory; this.simple = simple ?? throw new ArgumentNullException(nameof(simple), "no simple generator provided"); this.seeds = seeds ?? throw new ArgumentNullException(nameof(seeds), "no seed generator provided"); this.suppression = suppression ?? throw new ArgumentNullException(nameof(suppression), "no suppression provided, use AtomSuppression.None()"); }
/// <summary> /// Given the current configuration create an <see cref="IAtomHashGenerator"/>. /// </summary> /// <returns>instance of the generator</returns> /// <exception cref="ArgumentException">no depth or encoders were configured</exception> public IAtomHashGenerator Atomic() { if (depth < 0) { throw new ArgumentException("no depth specified, use .Depth(int)"); } List <IAtomEncoder> encoders = new List <IAtomEncoder>(); // set is ordered encoders.AddRange(encoderSet); encoders.AddRange(this.customEncoders); // check if suppression of atoms is wanted - if not use a default value // we also use the 'Basic' generator (see below) bool suppress = suppression != AtomSuppression.Unsuppressed; IAtomEncoder encoder = new ConjugatedAtomEncoder(encoders); SeedGenerator seeds = new SeedGenerator(encoder, suppression); AbstractAtomHashGenerator simple = suppress ? (AbstractAtomHashGenerator) new SuppressedAtomHashGenerator(seeds, new Xorshift(), MakeStereoEncoderFactory(), suppression, depth) : (AbstractAtomHashGenerator) new BasicAtomHashGenerator(seeds, new Xorshift(), MakeStereoEncoderFactory(), depth); // if there is a finder for checking equivalent vertices then the user // wants to 'perturb' the hashed if (equivSetFinder != null) { return(new PerturbedAtomHashGenerator(seeds, simple, new Xorshift(), MakeStereoEncoderFactory(), equivSetFinder, suppression)); } else { // no equivalence set finder - just use the simple hash return(simple); } }