Почему это лучше для использования'! =", чем' <' в векторном цикле? (C++)

1) Как вы правильно поняли, требование к масштабированию связано с дискретным преобразованием Фурье. Лучший способ получить это - вычислить деконволюцию двух унифицированных единичных сигналов. Их DFT равен n 0 0 0 ...., где n - количество точек DFT. Следовательно, отношение r_f равно 1 0 0 0 0, и его обратное БПФ, вычисленное с помощью np.fft.ifft(), равно 1 / n 1 / n 1 / n ... Правильный сигнал, полученный в результате деконволюции, должен был быть 1 / T 1 / T 1 / Т ..., где Т = 10. это длина кадра.

Как следствие, правильное масштабирование для выполнения деконволюции составляет n/T= len(r_f)/10.

r_if=r_if*len(r_if)/10.

2) Деконволюционный сигнал транслируется на половину периода. Это связано с тем, что ядро ​​Гаусса центрируется по центру кадра. Просто сдвиньте ядро ​​на половину периода, и проблема решена. Для этого можно применить функцию np.fft.fftshift():

f_yb = np.fft.fft(np.fft.fftshift(y_b))    #fft the filter

РЕДАКТИРОВАТЬ: Чтобы исследовать причину перевода, давайте сосредоточимся на случае, когда ядро ​​деконволюции является очень узким гауссовым распределением, почти соответствующим Распределение Дирака. Ваш входной сигнал представляет собой гауссову кривую с центром в нуле, а кадр дискретизируется между -5 и 5. Аналогично, ядро ​​деконволюции представляет собой дираковский центр с центром в нуле. Как следствие, деконволюция сигнала должна быть идентична входному сигналу: гауссова кривая с центром в нуле. Тем не менее, DFT, реализованный в FFTW и, следовательно, np.fft.fft() , вычисляется как кадр, начинающийся с 0 и заканчивающийся на 10 , который выбирается в точках 10j / n, где j находится в [0..n- 1], частоты в пространстве Фурье равны k / 10, где k в [0..n / 2, -n / 2 + 1 ..- 1]. Как следствие, этот ДПФ воспринимает ваш сигнал как гауссиан с центром в 5, а ядро ​​деконволюции - как дираковский с центром в 5. Свертка функции f (t) с дельтой Дирака (t-t0) с центром в точке t0 является просто переведенная функция f (t-t0). Следовательно, результатом деконволюции, вычисленной в np.fft.fft(), является входной сигнал, переведенный на половину периода. Поскольку входной сигнал центрируется на 0 в кадре [-5,5], выходной сигнал, вычисленный с помощью np.fft.fft(), центрируется на -5 (или эквивалентно 5 из-за периодичности). Сдвиг ядра устраняет несоответствие между тем, что мы думаем о кадре как [-5 5], и np.fft.ifft() обрабатываем его так, как если бы это было [0 10].

Фильтры часто предназначены для уменьшения влияния высокочастотных шумов. Таким образом, деконволюция вызывает потенциальное увеличение высокочастотного шума. Скрининг частот, как вы сделали, является потенциальным решением. Обратите внимание, что это точно эквивалентно свертке сигнала с определенным фильтром!

В диапазоне томографической реконструкции алгоритм отфильтрованного обратного проецирования требует применения линейного фильтра, который значительно раздувает высокочастотный шум. Здесь предложен фильтр Винера : этот тип фильтра может быть спроектирован так, чтобы минимизировать среднеквадратичную ошибку на деконволюционном сигнале, учитывая SNR извилистого сигнала. Тем не менее, требуется некоторое предположение относительно спектральной плотности мощности сигнала и шума.

10
задан 16 May 2009 в 04:07
поделиться

7 ответов

Поскольку вы используете итераторы, и это заставит цикл выглядеть точно так же, как и другие контейнеры, если вы решите переключиться на другие типы контейнеров, такие как set, list, unordered_set, и т.д., где <не имеет значения.

22
ответ дан 3 December 2019 в 13:47
поделиться

Я предполагаю, что вы имеете в виду использование ! = Vector.end () , а не , как это было не ясно из вашего вопроса.

Одна из причин предпочесть версию end () заключается в том, что вы действительно пытаетесь проверить, достигли ли вы конца.

Идиома для выполнения такого рода проверок массивов в C заключалась в проверке индекса по сравнению с размером, но это «устаревшее» поведение. Затем он был распространен в мире Java (как < array.length ) до тех пор, пока люди не осознали, что массивы - это зло и что Java, наконец, поддерживает дженерики. В C ++, однако, нет причин использовать эту идиому, когда у вас есть хороший класс коллекции, такой как vector, с которым можно работать. Он более читаемый и более удобный. Например,

8
ответ дан 3 December 2019 в 13:47
поделиться

Некоторые типы итераторов не поддерживают оператор «меньше» - они поддерживают только оператор неравенства. Вот почему вы часто будете видеть, что оператор «меньше чем» заброшен.

6
ответ дан 3 December 2019 в 13:47
поделиться

В общем, мне нравится помещать такой код в шаблонную функцию, аналогичную алгоритмам STL, так что они не зависят от того, что является основным контейнером.

Поскольку <имеет только смысл для векторов это было бы плохо для универсальной функции. Если вы используете <, вы ограничиваетесь использованием вектора.

3
ответ дан 3 December 2019 в 13:47
поделиться

It could be that the programmer remembered a defensive coding trick: In case something goes haywire during the loop's execution, and the index/pointer/iterator goes way past the end, the loop will quietly stop upon checking '<' leaving the bug unnoticed. With != there's likely to be chaos and a crash as the loop continues with bad data, allowing an earlier fix.

2
ответ дан 3 December 2019 в 13:47
поделиться

Для векторных итераторов это не имеет значения. Как правило, итераторы могут не поддерживать '<' just '==' и '! ='. Следовательно, наиболее общий способ проверить, не достигли ли вы конца коллекции, - это проверить, есть ли итератор! = Container.end ()

1
ответ дан 3 December 2019 в 13:47
поделиться

Другая причина: при преобразовании в сборку ветвь-равно или ветвь-не-равно обычно намного быстрее, чем ветвь сравнения.

-1
ответ дан 3 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: