Algorithm Implementation/Miscellaneous/Benford's Law
C#
edit /// <summary>
/// Por naturaleza ocurren distribuciones que abarcan varios órdenes de magnitud
/// No por códigos binarios, sistemas unarios o distribuciones estocásticas.
/// Ten cuidado, sólo aproxicamción, nunca es exacto. Te estoy advirtiendo ' esto es trivial. La ley de la trivialidad
/// </summary>
/// <param name="posicion">El real posicion del numero i.e. primero, segundo, etc.</param>
/// <param name="realDigito">El dígito concreto</param>
/// <param name="precision">El cantidad de los mumeros antes el posición decimal</param>
/// <returns></returns>
public double TanBenfordProb(int posicion, int realDigito, int precision)
{
if (posicion == 1 & realDigito == 0)
{
return double.NaN;
}
else if (posicion == 1 & realDigito != 0)
{
return Math.Round((Math.Log10((realDigito + 1.0) / realDigito)), precision);
}
else
{
double limInfer = Math.Pow(10, (posicion - 2));
double limSuper = Math.Pow(10, (posicion - 1)) - 1;
double Pd = 0d;
for (double i = limInfer; i <= limSuper; i++)
{
Pd += Math.Log10(1.0 + (1.0 / ((10.0 * i) + realDigito)));
}
return Math.Round(Pd, precision);
}
}
Java
edit /*
* Por naturaleza ocurren distribuciones que abarcan varios órdenes de magnitud
* No por códigos binarios, sistemas unarios o distribuciones estocásticas.
* Ten cuidado, sólo aproxicamción, nunca es exacto. Te estoy advirtiendo ' esto es trivial. La ley de la trivialidad
* @param posicion El real posicion del numero i.e. primero, segundo, etc
* @param realDigito El dígito concreto
* @param precision El cantidad de los mumeros antes el posición decimal
*/
public static double TanBenfordProb(int posicion, int realDigito, int precision){
if (posicion == 1 & realDigito == 0)
{
return Double.NaN;
}
else if (posicion == 1 & realDigito != 0)
{
return TanDecimalExactitud(Math.log10(Math.log10((realDigito + 1.0) / realDigito)), precision);
}
else
{
double limInfer = Math.pow(10, (posicion - 2));
double limSuper = Math.pow(10, (posicion - 1)) - 1;
double Pd = 0d;
for (double i = limInfer; i <= limSuper; i++)
{
Pd += Math.log10(1.0 + (1.0 / ((10.0 * i) + realDigito)));
}
return TanDecimalExactitud(Pd, precision);
}
}
private static double TanDecimalExactitud(double value, int precision){
BigDecimal bd = new BigDecimal(Double.toString(value));
bd = bd.setScale(precision, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}
Java (Junit)
edit
@Test
public void Evaluar_LeyBenford_Exito()
{
//Arrange
double[][] benford = new double[][]
{
{ Double.NaN, 0.301, 0.1761, 0.1249, 0.0969, 0.0792, 0.0669, 0.058, 0.0512, 0.0458 },
{ 0.1197, 0.1139, 0.1088, 0.1043, 0.1003, 0.0967, 0.0934, 0.0904, 0.0876, 0.085 },
{ 0.1018, 0.1014, 0.101, 0.1006, 0.1002, 0.0998, 0.0994, 0.099, 0.0986, 0.0983 },
{ 0.1002, 0.1001, 0.1001, 0.1001, 0.1, 0.1, 0.0999, 0.0999, 0.0999, 0.0998 },
{ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 }
//0.1 -> ad inf ->
};
//Act y Assert
for (int i = 1; i <= 9; i++){
for (int j = 0; j <= 9; j++){
assertEquals(Benford.TanBenfordProb(i, j, 4), benford[i][j], 0);
}
}
}