/** * Calculates the change in the statistic corresponding to this effect if * the given actor would change his behavior by the given amount. */ double AverageReciprocatedAlterEffect::calculateChangeContribution(int actor, int difference) { double contribution = 0; const OneModeNetwork * pNetwork = dynamic_cast<const OneModeNetwork *>(this->pNetwork()); if (!pNetwork) { throw runtime_error(string("One-mode network expected in ") + "AverageReciprocatedAlterEffect"); } if (pNetwork->reciprocalDegree(actor) > 0) { double totalAlterValue = 0; for (CommonNeighborIterator iter = pNetwork->reciprocatedTies(actor); iter.valid(); iter.next()) { double alterValue = this->centeredValue(iter.actor()); totalAlterValue += alterValue; } contribution = difference * totalAlterValue; if (this->ldivide) { contribution /= pNetwork->reciprocalDegree(actor); } } return contribution; }
/** * Calculates the contribution of a tie flip to the given actor. */ double SameCovariateTransitiveReciprocatedTripletsEffect::calculateContribution(int alter) const { // If we are introducing a tie from the ego i to the alter j, then each // two-path from i to j with an existing tie from j to i contributes one // unit; in addition, each configuration i <-> h <- j also contributes one // unit; the number of such configurations is stored in pRBTable. double contribution1 = 0; const Network * pNetwork = this->pNetwork(); const OneModeNetwork * pOneModeNetwork = dynamic_cast<const OneModeNetwork *>(pNetwork); if (this->inTieExists(alter) && this->inequalityCondition(this->value(alter) - this->value(this->ego()))) { contribution1 = this->pTwoPathTable()->get(alter); } for (CommonNeighborIterator iter = pOneModeNetwork->reciprocatedTies(this->ego()); iter.valid(); iter.next()) { int j = iter.actor(); if ((j != alter) && this->inequalityCondition(this->value(j) - this->value(this->ego())) && (pNetwork->tieValue(j, alter) >= 1)) { contribution1++; } } return contribution1; }
/** * Returns the statistic corresponding to the given ego with respect to the * given values of the behavior variable. */ double ReciprocatedSimilarityEffect::egoStatistic(int ego, double * currentValues) { const OneModeNetwork * pNetwork = dynamic_cast<const OneModeNetwork *>(this->pNetwork()); if (!pNetwork) { throw runtime_error(string("One-mode network expected in ") + "ReciprocatedSimilarityEffect"); } double statistic = 0; int neighborCount = 0; for (CommonNeighborIterator iter = pNetwork->reciprocatedTies(ego); iter.valid(); iter.next()) { int j = iter.actor(); if (!this->missing(this->period(), j) && !this->missing(this->period() + 1, j)) { double tieStatistic = this->similarity(currentValues[ego], currentValues[j]); if (this->lalterPopularity) { tieStatistic *= pNetwork->inDegree(j); } statistic += tieStatistic; neighborCount++; } } if (this->laverage && neighborCount > 0) { statistic /= neighborCount; } return statistic; }
/** * Returns the statistic corresponding to the given ego with respect to the * given values of the behavior variable. */ double AverageReciprocatedAlterEffect::egoStatistic(int i, double * currentValues) { const OneModeNetwork * pNetwork = dynamic_cast<const OneModeNetwork *>(this->pNetwork()); if (!pNetwork) { throw runtime_error(string("One-mode network expected in ") + "AverageReciprocatedAlterEffect"); } double statistic = 0; int neighborCount = 0; for (CommonNeighborIterator iter = pNetwork->reciprocatedTies(i); iter.valid(); iter.next()) { int j = iter.actor(); if (!this->missing(this->period(), j) && !this->missing(this->period() + 1, j)) { statistic += currentValues[j]; neighborCount++; } } if (neighborCount > 0) { statistic *= currentValues[i]; if (this->ldivide) { statistic /= neighborCount; } } return statistic; }
/** * Calculates the change in the statistic corresponding to this effect if * the given actor would change his behavior by the given amount. */ double ReciprocatedSimilarityEffect::calculateChangeContribution(int actor, int difference) { double contribution = 0; const OneModeNetwork * pNetwork = dynamic_cast<const OneModeNetwork *>(this->pNetwork()); if (!pNetwork) { throw runtime_error(string("One-mode network expected in ") + "ReciprocatedSimilarityEffect"); } if (pNetwork->reciprocalDegree(actor) > 0) { // The formula for the average similarity x reciprocity effect: // s_i(x) = avg(sim(v_i, v_j) - centeringConstant) over all // mutual neighbors j of i. // sim(v_i, v_j) = 1.0 - |v_i - v_j| / observedRange // We need to calculate the change delta in s_i(x), if we changed // v_i to v_i + d (d being the given amount of change in v_i). // To this end, we can disregard the centering constant and // compute the average change in similarity, namely, // avg(sim(v_i + d, v_j) - sim(v_i, v_j)) = // avg(1 - |v_i+d-v_j|/range - 1 + |v_i-v_j|/range) = // avg(|v_i-v_j| - |v_i+d-v_j|) / range, // the average being taken over all mutual neighbors of i. // The reasoning for other effects is similar. // This is what is calculated below. int oldValue = this->value(actor); int newValue = oldValue + difference; int totalChange = 0; for (CommonNeighborIterator iter = pNetwork->reciprocatedTies(actor); iter.valid(); iter.next()) { int j = iter.actor(); int alterValue = this->value(j); int change = abs(oldValue - alterValue) - abs(newValue - alterValue); if (this->lalterPopularity) { change *= pNetwork->inDegree(j); } totalChange += change; } contribution = ((double) totalChange) / this->range(); if (this->laverage) { contribution /= pNetwork->reciprocalDegree(actor); } } return contribution; }