sSize = Math.max(matchers[0].length, s.getNodeNum());
}
this.matchers = new BipartiteCavityMatcher[tSize][sSize];
}
BipartiteCavityMatcher matcher;
// initiation of the matchers
for (int i = 0; i < t.getNodeNum(); i++) {
for (int j = 0; j < s.getNodeNum(); j++) {
final int degI = t.outDeg(i);
final int degJ = s.outDeg(j);
matcher = factory.make(
degI,
degJ,
!MathOperations.isInfinity(costFunction.cost(
t.getLabel(i), s.getLabel(j))));
matchers[i][j] = matcher;
for (int u = 0; u < degI; u++) {
matcher.setDelCostX(u, t.weights[i][u]);
}
for (int u = 0; u < degJ; u++) {
matcher.setDelCostY(u, s.weights[j][u]);
}
}
}
if (tEdgeEncounters == null || tEdgeEncounters.length < t.getNodeNum()) {
tEdgeEncounters = new int[t.getNodeNum()];
}
Arrays.fill(tEdgeEncounters, 0, t.getNodeNum(), FIRST_TIME);
if (sEdgeEncounters == null || sEdgeEncounters.length < s.getNodeNum()) {
sEdgeEncounters = new int[s.getNodeNum()];
}
computationTime = System.currentTimeMillis();
double currScore, tmpScore; // , pruneAll
for (int et = 0; et < t.getEdgeNum(); et++) {
int fromT = t.edgeToNeighbors[et][0];
int toTNeighborIx = t.edgeToNeighbors[et][1];
int toT = t.outAdjLists[fromT][toTNeighborIx];
int fromTNeighborIx = t.getNeighborIx(toT, fromT);
Arrays.fill(sEdgeEncounters, 0, s.getNodeNum(), FIRST_TIME);
for (int es = 0; es < s.getEdgeNum(); es++) {
int fromS = s.edgeToNeighbors[es][0];
int toSNeighborIx = s.edgeToNeighbors[es][1];
int toS = s.outAdjLists[fromS][toSNeighborIx];
int fromSNeighborIx = s.getNeighborIx(toS, fromS);
matcher = matchers[toT][toS];
if (useCavity) {
if (sEdgeEncounters[toS] == SECOND_TIME) {
if (tEdgeEncounters[toT] == FIRST_TIME) {
matcher.processAllCavityMatchingY(fromTNeighborIx);
} else if (tEdgeEncounters[toT] == SECOND_TIME) {
matcher.processAllPairsCavityMatching();
}
}
}
final BipartiteCavityMatcher matcherToFrom = matchers[toT][fromS];
double cavityPrune = 0;
boolean foundForced = false;
// IMPROTANT: we assume that at most one forced match exists!!!
tmpScore = MathOperations.INFINITY;
final int tNeighborsSize = t.outAdjLists[toT].length;
for (int u = 0; u < tNeighborsSize; ++u) {
if (u != fromTNeighborIx) {
if (!MathOperations.isInfinity(t.weights[toT][u])) {
cavityPrune += t.weights[toT][u];
final double value = matcherToFrom.getMatchCostXY(u,
toSNeighborIx) - t.weights[toT][u];
if (MathOperations.greater(
tmpScore,
value)
&& !foundForced) {
tmpScore = value;
}
}
else {
if (foundForced) {
throw new RuntimeException(
"more than two forced matches!");
}
tmpScore = matcherToFrom.getMatchCostXY(u,
toSNeighborIx);
foundForced = true;
}
}
}
currScore = tmpScore + cavityPrune + t.smoothCost[toT];
final BipartiteCavityMatcher matcherFromTo = matchers[fromT][toS];
tmpScore = MathOperations.INFINITY;
foundForced = false;
cavityPrune = 0;
// pruneAll = 0;
final int sNeighborsSize = s.outAdjLists[toS].length;
for (int u = 0; u < sNeighborsSize; ++u) {
if (u != fromSNeighborIx) {
if (!MathOperations.isInfinity(s.weights[toS][u])) {
cavityPrune += s.weights[toS][u];
final double value = matcherFromTo.getMatchCostXY(toTNeighborIx,
u) - s.weights[toS][u];
if (MathOperations.greater(
tmpScore,
value)
&& !foundForced) {
tmpScore = value;
}
// pruneAll += s.weights[toS][u];
} else {
if (foundForced) {
throw new RuntimeException(
"more than two forced matches!");
}
tmpScore = matcherFromTo.getMatchCostXY(
toTNeighborIx, u);
foundForced = true;
}
}
}