Skip to content

Commit

Permalink
Align to BHoM/BHoM#1591
Browse files Browse the repository at this point in the history
(Introducing NumericalApproximationConfig)
  • Loading branch information
alelom committed Jan 26, 2024
1 parent af6c36c commit 5623d98
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 51 deletions.
3 changes: 1 addition & 2 deletions Analytical_Engine/Create/Graph/ComparisonConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ public static ComparisonConfig ComparisonConfig(double numericTolerance = oM.Geo
{
ComparisonConfig cc = new ComparisonConfig()
{
NumericTolerance = numericTolerance,
PropertiesToConsider = propertyNamesToConsider ?? new List<string>(),
NumericalApproximationConfig = new NumericalApproximationConfig() { NumericTolerance = numericTolerance },
PropertiesToConsider = propertyNamesToConsider ?? new HashSet<string>(),
};

Expand Down
21 changes: 12 additions & 9 deletions BHoM_Engine/Modify/PropertyNamesToFullNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static void PropertyNamesToFullNames(this BaseComparisonConfig comparison
// We need to process only those properties that have not been specified in FullName form, or that contain wildcards.
List<string> propertiesToConsiderToParse = comparisonConfig.PropertiesToConsider?.Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();
List<string> propertyExceptionsToParse = comparisonConfig.PropertyExceptions?.Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();
List<string> propertyNumericTolerancesToParse = comparisonConfig.PropertyNumericTolerances?.Select(p => p.Name).Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();
List<string> propertyNumericTolerancesToParse = comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances?.Select(p => p.Name).Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();

// If all the property names are already in FullName form and without wildcards, return.
if (!propertiesToConsiderToParse.Any() && !propertyExceptionsToParse.Any() && !propertyNumericTolerancesToParse.Any())
Expand All @@ -87,7 +87,7 @@ public static void PropertyNamesToFullNames(this BaseComparisonConfig comparison
bool processPropertiesExceptions = propertyExceptionsToParse.Any() && (!cache || !m_cachedPropertyExceptions.TryGetValue(propertyExceptionsCacheKey, out propertyExceptions_fullNames));

// Check if we already have encountered and cached this same object Type and PropertyNumericTolerances.
string propertyNumericTolerancesCacheKey = $"{type.FullName}:{string.Join(",", comparisonConfig.PropertyNumericTolerances?.Select(ct => ct.Name + ct.Tolerance))}";
string propertyNumericTolerancesCacheKey = $"{type.FullName}:{string.Join(",", comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances?.Select(ct => ct.Name + ct.Tolerance))}";
bool processPropertyNumericTolerances = propertyNumericTolerancesToParse.Any() && (!cache || !m_cachedPropertyNumericTolerances.TryGetValue(propertyNumericTolerancesCacheKey, out propertyNumericTolerances_fullNames));

// Safety clauses because C#'s Dictionary TryGetValue sets the out variable to `null` if it failed.
Expand Down Expand Up @@ -120,16 +120,16 @@ public static void PropertyNamesToFullNames(this BaseComparisonConfig comparison
{
foreach (var propNumericTolerance in propertyNumericTolerancesToParse)
if (IsMatchingInclusion(propertyFullName, propNumericTolerance))
propertyNumericTolerances_fullNames.Add(new NamedNumericTolerance() { Name = propertyFullName, Tolerance = comparisonConfig.PropertyNumericTolerances.Where(pnc => pnc.Name == propNumericTolerance).First().Tolerance });
propertyNumericTolerances_fullNames.Add(new NamedNumericTolerance() { Name = propertyFullName, Tolerance = comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances.Where(pnc => pnc.Name == propNumericTolerance).First().Tolerance });

if (cache) m_cachedPropertyNumericTolerances[propertyNumericTolerancesCacheKey] = propertyNumericTolerances_fullNames;
}
}

// Add the results to the ComparisonConfig.
comparisonConfig.PropertyNumericTolerances.UnionWith(propertyNumericTolerances_fullNames);
comparisonConfig.PropertiesToConsider.UnionWith(propertiesToConsider_fullNames);
comparisonConfig.PropertyExceptions.UnionWith(propertyExceptions_fullNames);
comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances.UnionWith(propertyNumericTolerances_fullNames);

m_ComparisonConfig_Type_processed[new Tuple<Type, object>(type, comparisonConfig)] = comparisonConfig;
}
Expand All @@ -150,7 +150,7 @@ public static void PropertyNamesToFullNames(this BaseComparisonConfig comparison
// We need to execute this method only if we have properties in the ComparisonConfig that have NOT been specified in FullName form, or that contain wildcards.
List<string> propertiesToConsiderToParse = comparisonConfig.PropertiesToConsider?.Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();
List<string> propertyExceptionsToParse = comparisonConfig.PropertyExceptions?.Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();
List<string> propertyNumericTolerancesToParse = comparisonConfig.PropertyNumericTolerances?.Select(p => p.Name).Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();
List<string> propertyNumericTolerancesToParse = comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances?.Select(p => p.Name).Where(p => !p.StartsWith("BH.") || p.Contains("*")).ToList() ?? new List<string>();

// If all the property names in the ComparisonConfig are already in FullName form and without wildcards, return.
if (!propertiesToConsiderToParse.Any() && !propertyExceptionsToParse.Any() && !propertyNumericTolerancesToParse.Any())
Expand Down Expand Up @@ -179,13 +179,10 @@ public static void PropertyNamesToFullNames(this BaseComparisonConfig comparison

foreach (var propNumericTolerance in propertyNumericTolerancesToParse)
if (IsMatchingInclusion(propertyFullName, propNumericTolerance))
propertyNumericTolerances_fullNames.Add(new NamedNumericTolerance() { Name = propertyFullName, Tolerance = comparisonConfig.PropertyNumericTolerances.Where(pnc => pnc.Name == propNumericTolerance).First().Tolerance });
propertyNumericTolerances_fullNames.Add(new NamedNumericTolerance() { Name = propertyFullName, Tolerance = comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances.Where(pnc => pnc.Name == propNumericTolerance).First().Tolerance });
}

// Add the results to the ComparisonConfig.
comparisonConfig.PropertyNumericTolerances = comparisonConfig.PropertyNumericTolerances == null ?
new HashSet<NamedNumericTolerance>(comparisonConfig.PropertyNumericTolerances?.Union(propertyNumericTolerances_fullNames))
: propertyNumericTolerances_fullNames;
if (comparisonConfig.PropertiesToConsider != null)
comparisonConfig.PropertiesToConsider.UnionWith(propertiesToConsider_fullNames);
else
Expand All @@ -195,6 +192,12 @@ public static void PropertyNamesToFullNames(this BaseComparisonConfig comparison
comparisonConfig.PropertyExceptions.UnionWith(propertyExceptions_fullNames);
else
comparisonConfig.PropertiesToConsider = new HashSet<string>(propertyExceptions_fullNames);

comparisonConfig.NumericalApproximationConfig = comparisonConfig.NumericalApproximationConfig ?? new NumericalApproximationConfig();
if (comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances != null)
comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances.UnionWith(propertyNumericTolerances_fullNames);
else
comparisonConfig.NumericalApproximationConfig.PropertyNumericTolerances = new HashSet<NamedNumericTolerance>(propertyNumericTolerances_fullNames);
}

/***************************************************/
Expand Down
21 changes: 7 additions & 14 deletions BHoM_Engine/Query/Hash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ public static string Hash(this IObject iObj, BaseComparisonConfig comparisonConf
// Parse the ComparisonConfig's `PropertiesToConsider` and `PropertyExceptions` and get them all as Full Names.
Modify.PropertyNamesToFullNames(cc, iObj);

// Verify that no numerical approximation is requested for objects belonging to Geometrical types.
m_isCompatibleWithGeometryHash = cc.IsCompatibleWithGeometryHash();

// ----- HASH -----

// Compute the defining string.
Expand Down Expand Up @@ -150,23 +147,23 @@ private static string HashString(object obj, BaseComparisonConfig cc, int nestin
else if (type.IsNumeric(enumsAsNumbers: false))
{
// If we didn't specify any custom tolerance/significant figures, just return the input.
if (cc.NumericTolerance == double.MinValue && cc.SignificantFigures == int.MaxValue
&& (!cc.PropertyNumericTolerances?.Any() ?? true) && (!cc.PropertySignificantFigures?.Any() ?? true))
if (cc.NumericalApproximationConfig.NumericTolerance == double.MinValue && cc.NumericalApproximationConfig.SignificantFigures == int.MaxValue
&& (!cc.NumericalApproximationConfig.PropertyNumericTolerances?.Any() ?? true) && (!cc.NumericalApproximationConfig.PropertySignificantFigures?.Any() ?? true))
return $"\n{tabs}" + obj.ToString();

if (type == typeof(double))
return $"\n{tabs}" + NumericalApproximation((double)obj, currentPropertyFullName, cc).ToString();
return $"\n{tabs}" + NumericalApproximation((double)obj, currentPropertyFullName, cc.NumericalApproximationConfig).ToString();

if (type == typeof(int))
return $"\n{tabs}" + NumericalApproximation((int)obj, currentPropertyFullName, cc).ToString();
return $"\n{tabs}" + NumericalApproximation((int)obj, currentPropertyFullName, cc.NumericalApproximationConfig).ToString();

// Fallback for any other floating-point numeric type.
if (type.IsNumericFloatingPointType())
return $"\n{tabs}" + NumericalApproximation(double.Parse(obj.ToString()), currentPropertyFullName, cc).ToString();
return $"\n{tabs}" + NumericalApproximation(double.Parse(obj.ToString()), currentPropertyFullName, cc.NumericalApproximationConfig).ToString();

// Fallback for any other integral numeric type.
if (type.IsNumericIntegralType())
return $"\n{tabs}" + NumericalApproximation(double.Parse(obj.ToString()), currentPropertyFullName, cc).ToString();
return $"\n{tabs}" + NumericalApproximation(double.Parse(obj.ToString()), currentPropertyFullName, cc.NumericalApproximationConfig).ToString();

}
else if (type.IsPrimitive || type == typeof(String))
Expand Down Expand Up @@ -237,11 +234,7 @@ private static string HashString(object obj, BaseComparisonConfig cc, int nestin
return (string)hashStringFromExtensionMethod;

if (cc.UseGeometryHash && typeof(IGeometry).IsAssignableFrom(type))
{
// Verify that no numerical approximation is requested for objects belonging to Geometrical types.
if (cc.IsCompatibleWithGeometryHash())
return GeometryHash((IGeometry)obj).ToString();
}
return GeometryHash((IGeometry)obj).ToString();

// If the object is an IObject (= a BHoM class), let's look at its properties.
// We only do this for IObjects (BHoM types) since we cannot guarantee full compatibility of the following procedure with any possible (non-BHoM) type.
Expand Down
8 changes: 4 additions & 4 deletions BHoM_Engine/Query/NumericTolerance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public static partial class Query
"If a CustomTolerance match is found for this property Full Name, then return it. " +
"If multiple matches are found, return the most sensistive tolerance among the matches. " +
"If no match is found, return the most sensitive tolerance (double.MinValue).")]
[Input("comparisonConfig", "Comparison Config from where tolerance information should be extracted.")]
[Input("numericalApproxConfig", "Numerical approximation Config containing the settings for Numerical Tolerance.")]
[Input("propertyFullName", "Full name (path) of the property for which we want to extract the numerical Tolerance.")]
public static double NumericTolerance(this BaseComparisonConfig comparisonConfig, string propertyFullName)
public static double NumericTolerance(this NumericalApproximationConfig numericalApproxConfig, string propertyFullName)
{
comparisonConfig = comparisonConfig ?? new ComparisonConfig();
numericalApproxConfig = numericalApproxConfig ?? new NumericalApproximationConfig();

return NumericTolerance(comparisonConfig.PropertyNumericTolerances, comparisonConfig.NumericTolerance, propertyFullName, false);
return NumericTolerance(numericalApproxConfig.PropertyNumericTolerances, numericalApproxConfig.NumericTolerance, propertyFullName, false);
}

/***************************************************/
Expand Down
16 changes: 8 additions & 8 deletions BHoM_Engine/Query/NumericalApproximation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,25 @@ public static partial class Query
[Description("Compute the approximation of a floating-point number for its comparison with other numbers, given specific ComparisonConfig settings.")]
[Input("number", "Number to approximate.")]
[Input("fullName", "Name of the number or of the property that holds this number. This name will be used to seek any matching custom tolerance/significant figure to apply for this approximation in the `comparisonConfig` input.")]
[Input("comparisonConfig", "Object that stores the settings that will used for the approximation.")]
public static double NumericalApproximation(this double number, string fullName = null, BaseComparisonConfig comparisonConfig = null)
[Input("numericalApproxConfig", "Object that stores the settings that will used for the approximation.")]
public static double NumericalApproximation(this double number, string fullName = null, NumericalApproximationConfig numericalApproxConfig = null)
{
comparisonConfig = comparisonConfig ?? new ComparisonConfig();
numericalApproxConfig = numericalApproxConfig ?? new NumericalApproximationConfig();

return NumericalApproximation(number, fullName, comparisonConfig.PropertyNumericTolerances, comparisonConfig.NumericTolerance, comparisonConfig.PropertySignificantFigures, comparisonConfig.SignificantFigures);
return NumericalApproximation(number, fullName, numericalApproxConfig.PropertyNumericTolerances, numericalApproxConfig.NumericTolerance, numericalApproxConfig.PropertySignificantFigures, numericalApproxConfig.SignificantFigures);
}

/***************************************************/

[Description("Compute the approximation of an integer number for its comparison with other numbers, given specific ComparisonConfig settings.")]
[Input("number", "Number to approximate.")]
[Input("fullName", "Name of the number or of the property that holds this number. This name will be used to seek any matching custom tolerance/significant figure to apply for this approximation in the `comparisonConfig` input.")]
[Input("comparisonConfig", "Object that stores the settings that will used for the approximation.")]
public static double NumericalApproximation(this int number, string fullName = null, BaseComparisonConfig comparisonConfig = null)
[Input("numericalApproxConfig", "Object that stores the settings that will used for the approximation.")]
public static double NumericalApproximation(this int number, string fullName = null, NumericalApproximationConfig numericalApproxConfig = null)
{
comparisonConfig = comparisonConfig ?? new ComparisonConfig();
numericalApproxConfig = numericalApproxConfig ?? new NumericalApproximationConfig();

return NumericalApproximation(number, fullName, comparisonConfig.PropertySignificantFigures, comparisonConfig.SignificantFigures);
return NumericalApproximation(number, fullName, numericalApproxConfig.PropertySignificantFigures, numericalApproxConfig.SignificantFigures);
}

/***************************************************/
Expand Down
8 changes: 4 additions & 4 deletions BHoM_Engine/Query/SignificantFigures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public static partial class Query
"If a CustomTolerance match is found for this property Full Name, then return it. " +
"If multiple matches are found, return the most sensistive among the matches. " +
"If no match is found, return `ComparisonConfig.SignificantFigures`.")]
[Input("comparisonConfig", "Comparison Config from where tolerance information should be extracted.")]
[Input("numericalApproxConfig", "Numerical approximation Config containing the settings for significant figures.")]
[Input("propertyFullName", "Full name (path) of the property for which we want to extract the numerical Tolerance.")]
public static int SignificantFigures(this BaseComparisonConfig comparisonConfig, string propertyFullName)
public static int SignificantFigures(this NumericalApproximationConfig numericalApproxConfig, string propertyFullName)
{
comparisonConfig = comparisonConfig ?? new ComparisonConfig();
numericalApproxConfig = numericalApproxConfig ?? new NumericalApproximationConfig();

return SignificantFigures(comparisonConfig.PropertySignificantFigures, comparisonConfig.SignificantFigures, propertyFullName);
return SignificantFigures(numericalApproxConfig.PropertySignificantFigures, numericalApproxConfig.SignificantFigures, propertyFullName);
}

/***************************************************/
Expand Down
8 changes: 4 additions & 4 deletions Diffing_Engine/Query/NumericalDifferenceInclusion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ public static partial class Query
[Input("number1", "First number to compare.")]
[Input("number2", "Second number to compare.")]
[Input("propertyFullName", "If the numbers are part of an object, full name of the property that owns them. This name will be used to seek matches in the ComparisoConfig named numeric tolerance/significant figures.")]
[Input("comparisonConfig", "Object containing the settings for this numerical comparison.")]
[Input("numericalApproxConfig", "Object containing the settings for this numerical comparison.")]
[Output("seenAsDifferent", "Whether the input numbers are seen as different, given the numerical approximations specified in the comparisonConfig.")]
public static bool NumericalDifferenceInclusion(this object number1, object number2, string propertyFullName = null, BaseComparisonConfig comparisonConfig = null)
public static bool NumericalDifferenceInclusion(this object number1, object number2, string propertyFullName = null, NumericalApproximationConfig numericalApproxConfig = null)
{
comparisonConfig = comparisonConfig ?? new ComparisonConfig();
numericalApproxConfig = numericalApproxConfig ?? new NumericalApproximationConfig();

return NumericalDifferenceInclusion(number1, number2, propertyFullName, comparisonConfig.PropertyNumericTolerances, comparisonConfig.NumericTolerance, comparisonConfig.PropertySignificantFigures, comparisonConfig.SignificantFigures);
return NumericalDifferenceInclusion(number1, number2, propertyFullName, numericalApproxConfig.PropertyNumericTolerances, numericalApproxConfig.NumericTolerance, numericalApproxConfig.PropertySignificantFigures, numericalApproxConfig.SignificantFigures);
}

/***************************************************/
Expand Down
Loading

0 comments on commit 5623d98

Please sign in to comment.