如何在MATLAB中实现Benford定律

时间:2010-04-08 18:13:17

标签: matlab benfords-law

我想实施本福特定律的一个版本(http://en.wikipedia.org/wiki/Benford%27s_law) 这基本上要求数字的第一个数字来分析分布。

1934---> 1
0.04 ---> 4
-56 ---> 5

你如何在MATLAB中做到这一点?

4 个答案:

答案 0 :(得分:4)

function res = first_digit(number)
    number = abs(number);
    res = floor(number / (10 ^ floor(log10(number))));
end

它适用于所有实数(请参阅gnovice对极端情况的评论)

答案 1 :(得分:2)

有几种方法可以做到这一点......

  • 使用REGEXP

    wholeNumber = 1934;                      %# Your number
    numberString = num2str(wholeNumber,16);  %# Convert to a string
    matches = regexp(numberString,'[1-9]','match');  %# Find matches
    firstNumber = str2double(matches{1});  %# Convert the first match to a double
    
  • 使用ISMEMBER

    wholeNumber = 0.04;                      %# Your number
    numberString = num2str(wholeNumber,16);  %# Convert to a string
    isInSet = ismember(numberString,'123456789');  %# Find numbers that are
                                                   %#  between 1 and 9
    numberIndex = find(isInSet,1);           %# Get the first number index
    firstNumber = str2double(numberString(numberIndex));  %# Convert to a double
    

修改

the MathWorks blogs之一出现了对该主题的一些讨论。那里提供了一些有趣的附加解决方案提出的一个问题是使用矢量化解决方案,所以这是我提出的一个矢量化版本:

numberVector = [1934 0.04 -56];
numberStrings = cellstr(num2str(numberVector(:),16));
firstIndices = regexp(numberStrings,'[1-9]','once');
firstNumbers = cellfun(@(s,i) s(i),numberStrings,firstIndices);

答案 2 :(得分:1)

使用log10和floor内置函数,

floor(x./10.^floor(log10(x)))

也返回数组中所有元素的第一个数字。

答案 3 :(得分:0)

让我添加另一个基于字符串的解决方案(矢量化):

FirstDigit = @(n) sscanf(num2str(abs(n(:)),'%e'), '%1d', numel(n));

并对这里提到的案例进行了测试:

>> FirstDigit( [1934 0.04 -56 eps(realmin)] )
ans =
     1
     4
     5
     4