00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SMALLRINGLINKAGE_H
00023 #define SMALLRINGLINKAGE_H
00024
00025 #include "SmallRing.h"
00026 #include "ResizeArray.h"
00027 #include "inthash.h"
00028 #include "Inform.h"
00029
00033 class LinkagePath {
00034 public:
00035 SmallRing path;
00036 int start_ring, end_ring;
00037
00038 LinkagePath(void) : path(), start_ring(-1), end_ring(-1) {}
00039 LinkagePath(SmallRing &p_path, int p_start_ring, int p_end_ring) {
00040 path = p_path;
00041 start_ring = p_start_ring;
00042 end_ring = p_end_ring;
00043 }
00044
00045 int num(void) { return path.num(); }
00046 int operator [](int i) { return path[i]; }
00047 void append(int i) { path.append(i); }
00048 void remove_last(void) { path.remove_last(); }
00049
00050 LinkagePath* copy(void) {
00051 LinkagePath *pathcopy;
00052 pathcopy = new LinkagePath(*path.copy(),start_ring,end_ring);
00053 return pathcopy;
00054 }
00055
00056 friend Inform& operator << (Inform &os, LinkagePath &lp) {
00057 os << lp.path << " [" << lp.start_ring << "," << lp.end_ring << "]";
00058 return os;
00059 }
00060 };
00061
00065 class LinkageEdge {
00066 public:
00067 int left_atom, right_atom;
00068 ResizeArray<LinkagePath *> paths;
00069
00070 LinkageEdge(int p_atom_left, int p_atom_right) : paths (1) {
00071 left_atom = p_atom_left;
00072 right_atom = p_atom_right;
00073 }
00074
00075 void addPath(LinkagePath &lp) {
00076 paths.append(&lp);
00077 }
00078
00079 friend Inform& operator << (Inform &os, LinkageEdge &le) {
00080 os << "(" << le.left_atom << "," << le.right_atom << ")";
00081 return os;
00082 }
00083 };
00084
00087 class SmallRingLinkages {
00088 private:
00089 inthash_t *edges_to_links;
00090
00091 public:
00092 ResizeArray<LinkageEdge *> links;
00093 ResizeArray<LinkagePath *> paths;
00094
00095 SmallRingLinkages(void) : links(1) {
00096 edges_to_links = new inthash_t;
00097
00098 inthash_init(edges_to_links,64);
00099 }
00100
00101 ~SmallRingLinkages(void) {
00102 inthash_destroy(edges_to_links);
00103 delete edges_to_links;
00104 }
00105
00106 void clear(void) {
00107 links.clear();
00108 paths.clear();
00109 inthash_destroy(edges_to_links);
00110
00111 inthash_init(edges_to_links,64);
00112 }
00113
00114 void addLinkagePath(LinkagePath &lp) {
00115 int i, atom_left, atom_right;
00116 LinkageEdge *link;
00117 atom_right = lp.path[0];
00118
00119 for (i=1;i<lp.path.num();i++) {
00120 atom_left = atom_right;
00121 atom_right = lp.path[i];
00122 link = getLinkageEdge(atom_left,atom_right);
00123 link->addPath(lp);
00124 }
00125
00126 paths.append(&lp);
00127 }
00128
00129 bool sharesLinkageEdges(LinkagePath &lp) {
00130 int i, atom_left, atom_right;
00131 LinkageEdge *link;
00132 atom_right = lp.path[0];
00133
00134 for (i=1;i<lp.path.num();i++) {
00135 atom_left = atom_right;
00136 atom_right = lp.path[i];
00137 link = getLinkageEdge(atom_left,atom_right);
00138 if (link->paths.num() > 1)
00139 return true;
00140 }
00141
00142 return false;
00143 }
00144
00145 LinkageEdge* getLinkageEdge(int atom_left, int atom_right) {
00146 int key, link_idx;
00147 LinkageEdge *link;
00148
00149 order_edge_atoms(atom_left,atom_right);
00150 key = get_link_key(atom_left,atom_right);
00151
00152 link_idx = inthash_lookup(edges_to_links, key);
00153 if (link_idx == HASH_FAIL) {
00154 link = new LinkageEdge(atom_left,atom_right);
00155 links.append(link);
00156 link_idx = int(links.num())-1;
00157 inthash_insert(edges_to_links,key,link_idx);
00158 }
00159
00160 return links[link_idx];
00161 }
00162
00163 void order_edge_atoms(int& atom_left, int& atom_right) {
00164 int t;
00165 if (atom_left > atom_right) {
00166 t = atom_left;
00167 atom_left = atom_right;
00168 atom_right = t;
00169 }
00170 }
00171
00172 int get_link_key(int al, int ar) {
00173
00174
00175
00176 return 1 + ar*(ar+1)/2 + al*(al+1)/2 + (al+1)*ar;
00177 }
00178
00179 friend Inform& operator << (Inform &os, SmallRingLinkages &srl) {
00180 int i, len;
00181
00182 os << "SmallRingLinkages:\n";
00183
00184 os << "Links:\n";
00185 len = int(srl.links.num());
00186 for (i=0; i < len; i++)
00187 os << "\t" << *(srl.links[i]) << "\n";
00188
00189 os << "Paths:\n";
00190 len = int(srl.paths.num());
00191 for (i=0; i < len; i++)
00192 os << "\t" << *(srl.paths[i]) << "\n";
00193
00194 return os;
00195 }
00196 };
00197
00198 #endif