Threshold calculation without "if else"

조회 수: 9 (최근 30일)
Kyle Wang
Kyle Wang 2015년 3월 10일
댓글: Guillaume 2015년 3월 11일
Given following logic
T=1, if x < m1
T=2, if x >= m1 && x < m2
T=3, if x >= m2 && x < m3
T=4, if x >= m3
x is a parameter; m1, m2, m3 are thresholds to determine the conversion from x to T. Is there a way to calculate T without using "if"? Say, "rem" or "mod" or something without logic operation?
  댓글 수: 4
Kyle Wang
Kyle Wang 2015년 3월 10일
ha, solved:
m = [m1, m2, m3];
div = floor(x./m);
reg_score = div./(div+eps);
reg = [1,reg_score(1),reg_score(2),reg_score(3)];
T = sum(reg)
Guillaume
Guillaume 2015년 3월 11일
편집: Guillaume 2015년 3월 11일
Never mind that your solution only works with scalars whereas ours work on matrices of any shape, you're using floating point division, one of the slowest operation for a processor instead of comparison, one of the fastest operation.
Kind of pointless really. Particularly, that div./(div+eps) which is just a slow and roundabout way of saying div >= 1.

댓글을 달려면 로그인하십시오.

채택된 답변

Guillaume
Guillaume 2015년 3월 10일
T = 1 + (x >= m1) + (x >= m2) + (x >= m3)
would work. May not be more efficient that if though.
  댓글 수: 5
Jan
Jan 2015년 3월 11일
@Guillaume: histc is the most efficient solution.
Guillaume
Guillaume 2015년 3월 11일
Timing comparison:
  • With scalar:
x = rand;
m1 = 0.25; m2 = 0.5; m3 = 0.75;
%method 1: my solution
timeit(@() 1 + (x >= m1) + (x >= m2) + (x >= m3), 1)
%method 2: Star's solution
timeit(@() 1*(x < m1) + 2*((x >= m1) & (x < m2)) + 3*((x >= m2) & (x < m3)) + 4*(x >= m3), 1)
%method 3: Kyle's solution
timeit(@() sum([1 floor(x./[m1 m2 m3]) ./ (floor(x./[m1 m2 m3]) + eps)]), 1)
%method 4: histc
timeit(@() histc(x, [-Inf m1 m2 m3 Inf]), 2)
%method 5: Image's solution
timeit(@() imquantize(x, [m1 m2 m3]), 1)
Timings:
  • method 1 (mine): 6.6384955612319e-06
  • method 2 (star): 8.68228864632548e-06
  • method 3 (kyle): 9.01446251150368e-06
  • method 4 (histc): 1.3435760719302e-05
  • method 5 (image): 2.7342570776026e-05
sum of logical is fastest, histc and imquantize are ten times slower. Kyle's method is surprisingly not too bad but still slower.
  • with matrices
x = rand(2000);
m1 = 0.25; m2 = 0.5; m3 = 0.75;
%method 1: my solution
timeit(@() 1 + (x >= m1) + (x >= m2) + (x >= m3), 1)
%method 2: Star's solution
timeit(@() 1*(x < m1) + 2*((x >= m1) & (x < m2)) + 3*((x >= m2) & (x < m3)) + 4*(x >= m3), 1)
%method 3: Kyle's solution
timeit(@() sum([1 floor(x./[m1 m2 m3]) ./ (floor(x./[m1 m2 m3]) + eps)]), 1)
%method 4: histc
timeit(@() histc(x, [-Inf m1 m2 m3 Inf]), 2)
%method 5: Image's solution
timeit(@() imquantize(x, [m1 m2 m3]), 1)
  • method 1 (mine): 0.0722110642432628
  • method 2 (star): 0.173027548846752
  • method 3 (kyle): Does not work!
  • method 4 (histc): 0.0570872784882915
  • method 5 (image): 0.05592453728061645
histc and imquantize are slightly faster (probably because they only loop once over the matrix). Kyle's method does not work on matrices / vectors

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Image Analyst
Image Analyst 2015년 3월 11일
There sure is, if you have the Image Processing Toolbox . The function is called imquantize() . Here's a full demo:
% T=1, if x < m1
% T=2, if x >= m1 && x < m2
% T=3, if x >= m2 && x < m3
% T=4, if x >= m3
x = imread('cameraman.tif');
subplot(1,2,1);
imshow(x);
levels = [50, 150, 230]; % The "m" threshold levels.
classifiedImage = uint8(imquantize(x, levels));
subplot(1, 2, 2);
imshow(classifiedImage, []);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
There is logic, but it's hidden - internal to the imquantize() function so you don't see it and you don't have to explicitly do logical operations yourself, you just call the function.

카테고리

Help CenterFile Exchange에서 Performance and Memory에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by