2013-12-20 3 views
1
range = min(x):0.0001:max(x); 
N = numel(range); 
x = sort(x); 
hit = 0; 
i=1; 

for j = 1:(N-1) 
    if range(j) <= x(i) && x(i) < range(j+1) 
     hit = hit + 1; 
     i = i+1; 
     if x(i) == x(i-1) 
      while x(i) == x(i-1) % If there are more than one of the same 
       hit = hit + 1;  % numbers in succession, this allows x and 
       i = i+1;   % hit to carry on incrementing. 
      end %while 
     end %if 
    end %if 
end %for 
disp(hit) 

Этот код сравнивает «диапазон» и «х». Он проверяет, находится ли «x» между значениями в «диапазоне», если так, счетчик «hit» получает приращение, а также текущее значение «x».MATLAB 'for' loop skipping IF statement

Проблема заключается в некоторых случайных значениях x (насколько я могу судить, что они являются случайными), хотя они должны удовлетворять неравенству в выражении «IF», ​​оператор «IF» игнорируется, цикл for продолжается и, таким образом, окончательное значение «хит» неверно.

«x» обычно представляет собой массив 1D около миллиона или около того.

для этого примера, давайте

`x = [-2.1792 -2.1759 -2.1758 -2.1748 -2.1658 -2.1648 -2.1646 -2.1604 -2.1603 -2.1550]` 

«хит» должен быть равен «10», но вместо этого выводит «2», так как он решает пропустить «если» заявление на «J = 35».

Чтобы уточнить. Когда 'J = 35', диапазон (J) = -2.1758 и я = 3 значение х (I) = - 2.1758

Я уверен, что:

range(j) <= x(i) && x(i) < range(j+1) 
-2.1758 <= -2.1758 && -2.1758 < -2.1757 %**edited, meant -2.1757 not -2.1759** 

Верна.

Надеюсь, я просто делаю что-то глупое здесь, чего я не вижу. Извините, если это плохо отформатированный вопрос, это мой первый здесь. Приветствия заранее.

+0

-2,1758 <-2,1759 это не так. Это логическая ошибка? Работает ли ваш код, если все значения положительные? –

+0

Извините, мой плохой, отредактированный до -2.1757. поэтому -2.1758 <-2.1757 истинно. – NathM

+0

Может быть, это обычная проблема при сравнении реальных чисел? http://stackoverflow.com/questions/8959452/matlab-double-comparison –

ответ

0

Последующий номер x(i) может пройти этот тест:

if range(j) <= x(i) && x(i) < range(j+1) 

не будучи равной к своему соседу:

if x(i) == x(i-1) 

Это может быть бесконечно большим, и, таким образом, вы переходите на следующий j и это вне пределов досягаемости. Ваше внутреннее while нуждается в том же состоянии, что и внешний if. И вы можете пропустить if COND while COND и просто сделать while COND, так как он будет работать так же.

+0

Я не совсем понимаю, что вы имеете в виду. Избавление от IF имеет смысл. Я не понимаю, как вы понимаете, что последующие значения пройдут? – NathM

+0

Рассмотрим последовательность чисел 1.00010, 1.00011, 1.00012. Все они падают между 1.0001 и 1.0002, но они не равны друг другу. –

+0

А я понимаю, что вы имеете в виду, спасибо. Тем не менее, каждое число точнее до четырех знаков после запятой, а диапазон «range» массива увеличивается на 0,0001, что означает, что между ними не может быть более одного числа. – NathM

0

Может ли следующий код не быть более простым, быстрым и дать тот же результат?

x = sort(x) 
hit = sum(diff(x)==0); 
+0

Не совсем, массив «x» не увеличивается на 0,0001, а только на массив «range». Поэтому, если последующие значения в массиве «x» больше, чем «0» друг от друга, они не должны учитываться. Мой текущий код может показаться совершенно бессмысленным в тот момент, когда я согласен, но я строю алгоритм для подсчета ящиков ... он, надеюсь, будет намного более чувствительным фрагментом кода, когда я закончу! – NathM