/// <summary> /// Calculates the marginal factors according to the marginal average tariff rating method. /// </summary> /// <returns>The mapping of each of the model's tariff attribute values to their marginal factors.</returns> protected override IReadOnlyDictionary <TariffAttributeValue, decimal> CalculateFactors() { IDictionary <TariffAttributeValue, decimal> factors = new Dictionary <TariffAttributeValue, decimal>(); foreach (TariffAttributeValue tariffAttributeValue in TariffData.TariffKeys.SelectMany(x => x).Distinct()) { decimal totalAmount = 0m; int totalCount = 0; foreach (TariffCell cell in TariffData[tariffAttributeValue]) { totalAmount += cell.ClaimsAmount; totalCount += cell.PolicyCount; } if (totalCount > 0) { factors[tariffAttributeValue] = (totalAmount / totalCount) / TariffData.ExpectedClaimsExpenditure(); } else { factors[tariffAttributeValue] = 0m; } } return(new ReadOnlyDictionary <TariffAttributeValue, decimal>(factors)); }
/// <summary> /// Iteratively calculates the marginal factors for each attribute value. /// </summary> /// <param name="attributeValues">Attribute values the marginal factors are to be calculated for.</param> /// <param name="factors">Starting values for the iterative calculation of the marginal factors.</param> /// <returns>True if the threshold indicating a significant change in factors was undercut, false otherwise.</returns> private bool CalculateFactorsIteratively(IEnumerable <TariffAttributeValue> attributeValues, ref IDictionary <TariffAttributeValue, decimal> factors) { bool thresholdReached = true; foreach (TariffAttributeValue attributeValue in attributeValues) { IEnumerable <ITariffKey> keys = TariffData.TariffKeys.Where(x => x.Contains(attributeValue)); decimal aggregate = 0m; foreach (ITariffKey key in keys) { decimal partialFactor = 1m; foreach (TariffAttributeValue differentAttributeValue in key.Where(x => !x.Equals(attributeValue))) { partialFactor *= factors[differentAttributeValue]; } aggregate += partialFactor * TariffData[key].PolicyCount; } decimal totalClaimsAmount = TariffData[attributeValue].Select(x => x.ClaimsAmount).Sum(); decimal factorAfterIteration = totalClaimsAmount / (TariffData.ExpectedClaimsExpenditure() * aggregate); thresholdReached = thresholdReached && (Math.Abs(factorAfterIteration - factors[attributeValue]) < _deltaThreshold); factors[attributeValue] = factorAfterIteration; } return(thresholdReached); }