Rosetta 3.5
Main Page
Related Pages
Namespaces
Classes
Files
Examples
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
src
core
chemical
automorphism.cc
Go to the documentation of this file.
1
// -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2
// vi: set ts=2 noet:
3
//
4
// (c) Copyright Rosetta Commons Member Institutions.
5
// (c) This file is part of the Rosetta software suite and is made available under license.
6
// (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7
// (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8
// (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9
10
/// @file core/chemical/automorphism.cc
11
///
12
/// @brief
13
/// @author Ian W. Davis
14
15
16
#include <
core/chemical/automorphism.hh
>
17
#include <
core/chemical/Atom.hh
>
18
19
#include <utility/vector1.hh>
20
21
22
namespace
core {
23
namespace
chemical {
24
25
/// @details First automorphism is the identity, [1 2 3 4 ... N]
26
/// The algorithm works its way through the list of atoms one at a time,
27
/// for each one trying to pair it with every other possible atom
28
/// (including itself) that isn't already paired with some earlier atom.
29
/// To be paired, the atoms need only be of the same chemical type;
30
/// for efficiency though, we also check that they have the same number of neighbors.
31
/// We also check that all the edges between the current atom and previously paired atoms
32
/// also exist between their paired counterparts (a condition for true automorphisms).
33
/// If we get to a point where we can't find a partner for some atom,
34
/// we know some earlier pairing is wrong, so we backtrack and try something else.
35
/// This algorithm would be more natural to represent recursively,
36
/// keeping state on the stack, but by "flattening" it like this we can use
37
/// the backtracking machinery to "resume" our search on the next call to next(),
38
/// thereby iterating over all the possible automorphisms.
39
/// The vector curr_[] thus takes the place of the stack, and used[] serves
40
/// to prevent two different atoms from being paired with the same partner simultaneously.
41
utility::vector1<Size>
42
AutomorphismIterator::next
()
43
{
44
Size
i = 1;
// one of the atoms
45
// used[i] = has atom i already been partnered with someone?
46
utility::vector1<bool>
used(
natoms_
,
false
);
47
while
(
true
) {
48
Size
const
j =
curr_
[i];
// i's partner atom (at the moment)
49
// We can (and do) get j > natoms_ on subsequent calls to next();
50
// this should skip down to the "backtracking" code in the else block.
51
if
( j <=
natoms_
&& !used[j] &&
can_pair
(i, j) &&
edges_match
(i) ) {
52
used[j] =
true
;
53
++i;
// look for a partner for the next i
54
if
( i >
natoms_
) {
55
// They've all been partnered successfully! Yay!
56
utility::vector1<Size>
retval =
curr_
;
// make a copy
57
++
curr_
[
natoms_
];
// try the next atom when we come back
58
return
retval;
59
}
60
}
else
{
61
while
(
true
) {
62
++
curr_
[i];
// try the next atom
63
if
(
curr_
[i] >
natoms_
) {
64
// Oops, there is no next atom!
65
// Reset curr_[] for this atom and subsequent ones;
66
// pop up to previous i and increment it instead.
67
for
(
Size
k = i; k <=
natoms_
; ++k)
curr_
[k] = 1;
68
--i;
69
// I think we'd only get i < 0 if someone calls next() again
70
// after it returns the empty list; i == 0 is the proper end condition.
71
if
( i <= 0 ) {
72
// We've reached the end; return an empty list as a signal
73
return
empty_list_
;
74
}
75
used[
curr_
[i] ] =
false
;
76
}
else
{
77
break
;
// there's a next atom to try, so we're done
78
}
79
}
// end while loop for finding next permutation to try
80
}
// end if/else for trying to pair i and j
81
}
// end infinite while()
82
return
empty_list_
;
// to make compiler happy -- never get here
83
}
84
85
inline
86
bool
87
AutomorphismIterator::can_pair
(
Size
i,
Size
j) {
88
return
restype_
->atom(i).atom_type_index() ==
restype_
->atom(j).atom_type_index()
89
&&
restype_
->nbrs(i).size() ==
restype_
->nbrs(j).size();
90
}
91
92
}
// namespace chemical
93
}
// namespace core
Generated on Sat Jun 1 2013 11:31:34 for Rosetta 3.5 by
1.8.4