我想實現Benford定律的一個版本(http://en.wikipedia.org/wiki/Benford%27s_law) ,它基本上要求數字的第一位數字進行分佈分析。如何在MATLAB中實現Benford定律
1934---> 1
0.04 ---> 4
-56 ---> 5
你如何在MATLAB中做到這一點?
我想實現Benford定律的一個版本(http://en.wikipedia.org/wiki/Benford%27s_law) ,它基本上要求數字的第一位數字進行分佈分析。如何在MATLAB中實現Benford定律
1934---> 1
0.04 ---> 4
-56 ---> 5
你如何在MATLAB中做到這一點?
你可以做到這一點的幾種方法...
使用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);
function res = first_digit(number)
number = abs(number);
res = floor(number/(10^floor(log10(number))));
end
它適用於所有實數(見極端的情況下gnovice的評論)
使用log10和floor內置函數,
floor(x./10.^floor(log10(x)))
返回數組中所有元素的第一位數字。
讓我補充另一種基於字符串的解決方案(矢量和):
FirstDigit = @(n) sscanf(num2str(abs(n(:)),'%e'), '%1d', numel(n));
,並就案件這裏提到:
>> FirstDigit([1934 0.04 -56 eps(realmin)])
ans =
1
4
5
4
哎呦,答應我沒有抄你的答案,亞辛!當我找出我的解決方案時,您必須發佈信息。考慮使用abs()來覆蓋那些討厭的否定。 – Doresoom 2010-04-08 18:41:18
+1:我知道可能有某種方法可以在數學上做到這一點,但我認爲的第一種解決方案是基於字符串的。 – gnovice 2010-04-08 18:43:27
@gnovive:謝謝。更正了! – yassin 2010-04-08 18:47:26